機器學習實戰篇——用卷積神經網路演算法在Kaggle上跑個分
之前的文章簡單介紹了Kaggle平臺以及如何用支撐向量(SVM)的機器學習演算法識別手寫數字圖片。可見即使不用神經網路,傳統的機器學習演算法在影象識別的領域也能取得不錯的成績(我跑出來了97.2% 的正確率), 但是要將正確率再往上提升就會遇到瓶頸了。
此時,神經網路以及深度學習,尤其是卷積神經網路(CNN)就派上用場了。
用CNN的網路,在同樣的平臺上,目前我將手寫圖片識別的正確率提高到了99.1%,排名全球900多名左右。
1、匯入庫檔案
使用深度學習的方法當然就要用到大名鼎鼎的TensorFlow。
import pandas as pd
import math
import numpy as np
import matplotlib.pyplot as plt, matplotlib.image as mpimg
from sklearn.model_selection import train_test_split
import tensorflow as tf
%matplotlib inline
2、準備資料
與之前一樣,需要對資料進行分成Train 和 Test 兩個組。
labeled_images = pd.read_csv('train.csv')
images = labeled_images.iloc[:,1:]
labels = labeled_images.iloc[:,:1]
train_images, test_images,train_labels, test_labels = train_test_split(images, labels, test_size=0.02)
3、建立幫助函式
這是本問最難的部分,作用實際上就是對資料進行處理,轉換成TensorFlow 讀得懂的資料。
One Hot Encode
我們知道,這些圖片的標籤(識別結果)就是是0到9的10個數字,結果就是一個nx1的矩陣,n是訓練樣本的個數。為了讓模型更加方便地處理資料(計算機是二進位制的,最好給它0,1的資料),需要將資料轉換成nx10的矩陣。比如果其中一個樣板的標記是3,那麼這一行的數列就應該是[0,0,0,1,0,0,0,0,0,0], 如果是9的話[0,0,0,0,0,0,0,0,0,1]。所有的樣本疊起來就是一個nx10的矩陣。
def one_hot_encode(vec, vals=10):
'''
For use to one-hot encode the 10- possible labels
'''
n = len(vec)
out = np.zeros((n, vals))
out[range(n), vec] = 1
return out
幫助類
從AI學習筆記——卷積神經網路(CNN)的文章中我們知道,一張圖片有三個維度——長,寬,顏色通道。對於本文中的黑色圖片,第三個維度為1。在加上樣本的個數(n),整個訓練樣本應該是一個(nx28x28x1)的四維Tensor(張量)。set_up_images(self)函式就是將圖片轉換成這樣的Tensor。next_batch()函式則是n個訓練樣本分成若干個batch, 一個一個地送給模型(這個叫mini batch)。
class CifarHelper():
def __init__(self):
self.i = 0
# Intialize some empty variables for later on
self.training_images = None
self.training_labels = None
self.test_images = None
self.test_labels = None
def set_up_images(self):
print("Setting Up Training Images and Labels")
# Vertically stacks the training images
self.training_images = train_images.as_matrix()
train_len = self.training_images.shape[0]
# Reshapes and normalizes training images
self.training_images = self.training_images.reshape(train_len,28,28,1)/255
# One hot Encodes the training labels (e.g. [0,0,0,1,0,0,0,0,0,0])
self.training_labels = one_hot_encode(train_labels.as_matrix().reshape(-1), 10)
print("Setting Up Test Images and Labels")
# Vertically stacks the test images
self.test_images = test_images.as_matrix()
test_len = self.test_images.shape[0]
# Reshapes and normalizes test images
self.test_images = self.test_images.reshape(test_len,28,28,1)/255
# One hot Encodes the test labels (e.g. [0,0,0,1,0,0,0,0,0,0])
self.test_labels = one_hot_encode(test_labels.as_matrix().reshape(-1), 10)
def next_batch(self, batch_size):
# Note that the 100 dimension in the reshape call is set by an assumed batch size of 100
x = self.training_images[self.i:self.i+batch_size]
y = self.training_labels[self.i:self.i+batch_size]
self.i = (self.i + batch_size) % len(self.training_images)
return x, y
最後這兩行程式碼就完成了資料的初始化。
# Before Your tf.Session run these two lines
ch = CifarHelper()
ch.set_up_images()
# During your session to grab the next batch use this line
# (Just like we did for mnist.train.next_batch)
# batch = ch.next_batch(100)
4、建立模型
這裡用到了TensorFlow, 也許會之後在單獨的文章中介紹如何使用,這裡簡單介紹一下。
使用TensorFlow 首先是要建立一個 computation graph(計算圖譜),也就是先告訴計算機模型是怎樣的,包括神經網路有多少層,每層多少個神經元,輸入輸出資料的格式是怎的。此時還沒有開始計算。
Placeholder
x 輸入,y輸出,hold_prob用於dropout(不多解釋,主要用於隨機丟棄神經元的一種正則化的方法)
x = tf.placeholder(tf.float32, shape=[None,28,28,1])
y_true = tf.placeholder(tf.float32, shape=[None,10])
hold_prob = tf.placeholder(tf.float32)
Help functions
這些函式是為了簡化Tensorflow 建立神經網路的方法,根據從之前文章對CNN的介紹,我們需要卷積層,Pooling(池化)層,以及全連線層等等。
def init_weights(shape):
init_random_dist = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(init_random_dist)
def init_bias(shape):
init_bias_vals = tf.constant(0.1, shape=shape)
return tf.Variable(init_bias_vals)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
# x -->[batch, in_height, in_width, in_channels]
# W --> [filter_height, filter_width, in_channels, out_channels]
def max_pool_2by2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
def convolutional_layer(input_x, shape):
W = init_weights(shape)
b = init_bias([shape[3]])
return tf.nn.relu(conv2d(input_x, W) + b)
def normal_full_layer(input_layer, size):
input_size = int(input_layer.get_shape()[1])
W = init_weights([input_size, size])
b = init_bias([size])
return tf.matmul(input_layer, W) + b
搭建神經網路
第一層,卷積+Pooling
convo_1 = convolutional_layer(x,shape=[6,6,1,32])
convo_1_pooling = max_pool_2by2(convo_1)
第二層
convo_2 = convolutional_layer(convo_1_pooling,shape=[6,6,32,64])
convo_2_pooling = max_pool_2by2(convo_2)
第三層, 全連線
convo_2_flat = tf.reshape(convo_2_pooling,[-1,7*7*64])
full_layer_one = tf.nn.relu(normal_full_layer(convo_2_flat,1024))
Dropout 和 輸出
full_one_dropout = tf.nn.dropout(full_layer_one,keep_prob=hold_prob)
y_pred = normal_full_layer(full_one_dropout,10)
定義損失函式,和優化函式,初始化
Loss Function
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_pred))
Optimizer
optimizer = tf.train.AdamOptimizer(learning_rate=0.00002)
train = optimizer.minimize(cross_entropy)
Intialize Variables
init = tf.global_variables_initializer()
5、訓練模型
之前的準備工作妥當之後,實際上訓練模型的程式碼就很短了。用Tensorflow訓練模型,都必須在一個Session 之內並且初始化(都是套路)。
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
真正的程式碼就這兩行, 實際上就是將之前幫助函式中定義的mini batch 送到模型中進行訓練。
for i in range(50000):
batch = ch.next_batch(100)
sess.run(train, feed_dict={x: batch[0], y_true: batch[1], hold_prob: 0.5})
模型要進行50000次的迭代,我們需要將每100此迭代的結果列印出來。完整程式碼如下
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(50000):
batch = ch.next_batch(100)
sess.run(train, feed_dict={x: batch[0], y_true: batch[1], hold_prob: 0.5})
# PRINT OUT A MESSAGE EVERY 100 STEPS
if i%100 == 0:
print('Currently on step {}'.format(i))
print('Accuracy is:')
# Test the Train Model
matches = tf.equal(tf.argmax(y_pred,1),tf.argmax(y_true,1))
acc = tf.reduce_mean(tf.cast(matches,tf.float32))
print(sess.run(acc,feed_dict={x:ch.test_images,y_true:ch.test_labels,hold_prob:1.0}))
print('\n')
saver.save(sess,'models_saving/my_model.ckpt')
最後得到了98%的準確率
Currently on step 0
Accuracy is:
0.179762
Currently on step 100
Accuracy is:
0.584524
....
....
....
Currently on step 49900
Accuracy is:
0.983333
至此,一個完整的用Tensorflow 訓練CNN的過程就介紹完了,當然要最後還需要儲存模型,用模型對新的資料進行預測,關於這部分的內容就留給讀者自己吧。
————
相關文章
AI學習筆記——神經網路和深度學習
AI學習筆記——卷積神經網路1(CNN)
————
文章首發steemit.com 為了方便牆內閱讀,搬運至此,歡迎留言或者訪問我的Steemit主頁
相關文章
- 文字分類(下)-卷積神經網路(CNN)在文字分類上的應用文字分類卷積神經網路CNN
- 【卷積神經網路學習】(4)機器學習卷積神經網路機器學習
- 機器學習演算法(5):卷積神經網路原理及其keras實現機器學習演算法卷積神經網路Keras
- Keras上實現卷積神經網路CNNKeras卷積神經網路CNN
- 卷積神經網路卷積神經網路
- TensorFlow上實現卷積神經網路CNN卷積神經網路CNN
- 【深度學習篇】--神經網路中的卷積神經網路深度學習神經網路卷積
- TensorFlow實戰卷積神經網路之LeNet卷積神經網路
- 5.2.1 卷積神經網路卷積神經網路
- 卷積神經網路概述卷積神經網路
- 解密卷積神經網路!解密卷積神經網路
- 卷積神經網路CNN卷積神經網路CNN
- 卷積神經網路初探卷積神經網路
- 卷積神經網路-1卷積神經網路
- 卷積神經網路-2卷積神經網路
- 卷積神經網路-3卷積神經網路
- 【機器學習基礎】卷積神經網路(CNN)基礎機器學習卷積神經網路CNN
- 卷積神經網路-啟用函式卷積神經網路函式
- 卷積神經網路中的Winograd快速卷積演算法卷積神經網路演算法
- 圖卷積神經網路分類的pytorch實現卷積神經網路PyTorch
- 卷積神經網路四種卷積型別卷積神經網路型別
- 全卷積神經網路FCN卷積神經網路
- 深度剖析卷積神經網路卷積神經網路
- 看懂卷積神經網路(CNN)卷積神經網路CNN
- 卷積神經網路-AlexNet卷積神經網路
- 資料探勘(10):卷積神經網路演算法的一個實現卷積神經網路演算法
- 卷積神經網路:卷積層和池化層卷積神經網路
- 神經網路之卷積篇:詳解經典網路(Classic networks)神經網路卷積
- 卷積神經網路(CNN)反向傳播演算法卷積神經網路CNN反向傳播演算法
- 神經網路入門(二)卷積網路在影像識別的應用神經網路卷積
- 卷積神經網路 part2卷積神經網路
- CNN神經網路之卷積操作CNN神經網路卷積
- 卷積神經網路(CNN)詳解卷積神經網路CNN
- 14 卷積神經網路(進階)卷積神經網路
- 何為神經網路卷積層?神經網路卷積
- 卷積神經網路的缺點卷積神經網路
- 神經網路之卷積篇:詳解卷積步長(Strided convolutions)神經網路卷積IDE
- 吳恩達《卷積神經網路》課程筆記(1)– 卷積神經網路基礎吳恩達卷積神經網路筆記