1.tf.nn.lrn(pool_h1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 局部響應歸一化,使用相同位置的先後的filter進行響應歸一化操做git
參數說明:pool_h1表示輸入數據,4表示使用先後幾層進行歸一化操做,bias表示偏移量,alpha和beta表示係數數組
局部響應的公式 網絡
針對上述公式,作了一個試驗代碼:dom
# 本身編寫的代碼, 對x的[1, 1, 1, 1]進行局部響應歸一化操做,最後結果是相同的
x = np.array([i for i in range(1, 33)]).reshape([2, 2, 2, 4]) sqr_sum = np.zeros_like(x) sqr_sum[1, 1, 1, 1] = sum(x[1, 1, 1, 0:3] ** 2) print(sqr_sum[1, 1, 1, 1]) z = (x[1, 1, 1, 1] / (0 + sqr_sum[1, 1, 1, 1]*1)) ** 1 print(z)
# 調用的代碼 sess = tf.Session() y = tf.nn.lrn(input=x, depth_radius=1, bias=0, alpha=1, beta=1) print(sess.run(y[1, 1, 1, 1]))
2.random.sample(np.arange(N), cols*rows) # 從列表n中,挑選出cols*rows個數據ide
參數說明:np.arange(N) 表示列表,cols*rows表示挑選的數字個數函數
3.tf.one_hot(X, len(names), axis=-1) # 將一維標籤轉換爲one-hot類型優化
參數說明:X表示輸入的一維標籤,len(names)表示一個數字變成多少個維度,axis表示所在的位置編碼
使用Tensorflow卷積神經網絡對cifar10進行分類spa
數聽說明:cifar數據是由data :50000*3072, labels=3072個橫向量組成,類別名爲['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']code
在下面的操做中,須要使用tf,one_hot(labels, len(names), axis=-1) # 將標籤轉換爲one-hot的編碼類型
代碼說明:
代碼由三部分組成:第一部分,數據的讀入和裁剪以及標準化處理
第二部分:對W和卷積過程當中的卷積結果進行展現
第三部分:對圖像卷積參數進行訓練
第一部分:模型的讀入和裁剪以及標準化操做
第一步:構建unpickle函數進行數據的讀入
第二步:構建clean函數,
第一步:改變矩陣的維度爲[-1, 3, 32, 32]
第二步:.mean(1) 對3這個通道求平均值,表示對圖像進行灰度化處理,即RGB三個通道求平均
第三步:使用[:, 4:28, 4:28] 對圖像進行裁剪
第四步:.reshape([(len(), -1)]) 將圖像轉換爲二維矩陣
第五步:使用np.mean() 計算圖像的平均值, 並使用.reshape([len(), 1]) 對維度進行重構
第六步:使用np.std計算圖像的標準差,並使用.reshape([len(), 1]) 對維度進行重構,對於一些標準差較大的值,使用1/sqrt(len()) 代替
第七步:對圖像減去均值除以標準差來進行標準化操做
第三步:數據的讀入
第一步:讀入標籤的名字
第二步:循環,讀取data和labels,將每次讀取的data,使用np.vstack進行豎着串接,對於labels使用np.hstack進行橫着串接
第三步:使用clean來對數據作預處理,.astype轉換數據的類型
第四步:返回名字,data和labels
第四步:隨機的圖片展現
第一步:定義rows和cols的大小
第二步:使用random.sample(np.arange(N), rows*cols) 從數組中隨機挑選rows*cols個數做爲索引值
第三步:循環,plt.subplot構造子圖,plt.title(name[label[randix[i]]]) 構造題目
第四步:對圖像進行維度變化,使用plt.imshow()進行做圖操做
import numpy as np import matplotlib.pyplot as plt import tensorflow as tf import pickle import random # 設置隨機種子 random.seed(1) # 第一步:構造unpick用於讀取數據 def unpickle(filename): # 打開文件,二進制格式 f = open(filename, 'rb') # 文件的載入,編碼方式爲'latin1' out = pickle.load(f, encoding='latin1') f.close() return out # 第二步:對圖片進行預處理,灰度化,裁剪,標準化 def clean(data): # 圖像的維度轉換 data_reshaped = data.reshape(-1, 3, 32, 32) # 進行灰度化處理 gray_img = data_reshaped.mean(1) # 對圖像進行裁剪 gray_img_crop = gray_img[:, 4:28, 4:28] # 將圖像的維度轉換爲原來的二維數據 gray_img_crop = gray_img_crop.reshape([len(gray_img_crop), -1]) # 求得圖像的均值 mean = np.mean(gray_img_crop, axis=1) # 將均值的維度轉換爲2維,以便用於後續的相減操做 meanT = mean.reshape([len(mean), 1]) # 求得圖像的標準差 std = np.std(gray_img_crop, axis=1) # 將標準差轉換爲2維形式 stdT = std.reshape([len(std), 1]) # 若是標準差過大,使用1/np.sqrt(len(stdT)代替) adj_std = np.maximum(stdT, 1/np.sqrt(len(stdT))) # 進行標準化操做 normalize = (gray_img_crop - meanT) / adj_std return normalize # 第三步:數據的載入 def load_data(filename): # 數據標籤名的讀入 names = unpickle('{}/batches.meta'.format(filename))['label_names'] data = [] labels = [] for i in range(1, 6): # 循環讀取,每個文件的數據和標籤名 data_dict = unpickle('{}/data_batch_{}'.format(filename, i)) if len(data) > 0 : # 對數據進行豎着串接 data = np.vstack((data, data_dict['data'])) # 對標籤進行橫着串接 labels = np.hstack((labels, data_dict['labels'])) else: data = data_dict['data'] labels = data_dict['labels'] # 對數據進行預處理操做 data = clean(data) # 將數據的類型轉換爲np.float32 data = data.astype(np.float32) # 返回標籤名,數據,標籤 return names, data, labels names, data, labels = load_data('./cifar-10-batches-py') print(names) # 第四步:進行圖像的隨機展現 def show_random_img(names, data, labels): # 數據的大小 N = data.shape[0] # 橫和列的個數 rows, cols = 4, 8 # 從N個數據列表中,隨機挑選4*8個數據的索引值 randix = random.sample(range(N), rows*cols) plt.figure() for i in range(rows * cols): # 循環,構造每個圖的子圖 plt.subplot(rows, cols, i+1) # 得到單個的索引值 j = randix[i] # 文章名 ,使用標籤對應的類別名 plt.title(names[labels[j]]) # 圖像的維度轉換 img = data[j,:].reshape([24, 24]) # 圖片的展現 plt.imshow(img, cmap='Greys_r') plt.axis('off') plt.tight_layout() plt.show() show_random_img(names, data, labels)
第二部分:選擇一張圖片,做爲輸入數據,對卷積過程當中的W,conv,pool分別進行展現
第一步:選擇一張圖片,進行維度的變化,使用plt.imshow() 進行圖像的展現
第二步:構造初始參數
第一步:使用tf.reshape[row_img, [-1, 24, 24, 1]] 對x進行維度的變化
第二步:構造W和b,同時對x進行卷積,激活和池化操做
第三步:構造展現卷積層的函數,構造cols和rows進行子圖展現,循環通道數,展現第一張圖片的第i個通道的圖片
第四步:構造展現W參數的函數,構造cols和rows進行子圖展現,循環filter數,展現第一個通道的第i個filter的圖片
第五步:構造執行函數sess,使用sess.run()得到數組,調用函數進行展現
# 第二部分:進行卷積過程當中的圖像展現 # 第一步:隨機選擇一張圖,進行卷積圖和參數圖的演示 row_img = data[4,:] # 圖像維度的變化 row_img = row_img.reshape([24, 24]) plt.figure() plt.imshow(row_img, cmap='Greys_r') plt.show() # 第二步:將圖片進行維度變換,構造參數,並進行卷積,激活和池化操做 x = tf.reshape(row_img, shape=[-1, 24, 24, 1]) # 卷積的維度爲[5, 5, 1, 32] 5和5表示維度,1表示通道數,32表示filter個數 W1 = tf.Variable(tf.random_normal([5, 5, 1, 32])) # 構造b1參數,維度爲[32] b1 = tf.Variable(tf.random_normal([32])) # 進行一次卷積操做,strides表示步長 conv = tf.nn.conv2d(x, W1, strides=[1, 1, 1, 1], padding='SAME') # 加上偏置項b conv_with_b = tf.add(conv, b1) # 使用激活函數進行激活 conv_out = tf.nn.relu(conv_with_b) # 池化操做 k = 2 max_pool = tf.nn.max_pool(conv_out, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME') # 第三步:構造函數,進行卷積過程當中的圖像展現 def show_conv_img(conv_out, filename=None): # rows,cols的大小 rows, cols = 4, 8 # 循環,卷積圖像的通道數 for i in range(conv_out.shape[3]): # 選擇第一個圖像的i通道 img = conv_out[0, :, :, i] # 構造子圖 plt.subplot(rows, cols, i+1) # 圖像的展現 plt.imshow(img, cmap='Greys_r') # 關閉座標軸 plt.axis('off') # 圖像更窄的顯示 plt.tight_layout() if filename: plt.savefig(filename) else: plt.show() # 第四步:進行W參數的展現 def show_W(W, filename=None): # rows,cols的表示 rows, cols = 4, 8 plt.figure() # 循環W的filter個數 for i in range(W.shape[3]): # 圖片表示爲第1個通道的i個filter img = W[:, :, 0, i] # 構造子圖 plt.subplot(rows, cols, i+1) plt.imshow(img, cmap='Greys_r') plt.axis('off') plt.tight_layout() if filename: plt.savefig(filename) else: plt.show() # 第五步:進行卷積圖像和w的展現 with tf.Session() as sess: # 變量的初始化操做 sess.run(tf.global_variables_initializer()) # 將tf數據類型轉換爲數組類型,用於展現, 卷積層的展現 conv_val = sess.run(conv) print('conv:') show_conv_img(conv_val) # W1參數的展現 W_val = sess.run(W1) print('w:') show_W(W_val) # 卷積+激活後的圖像展現 conv_out_val = sess.run(conv_out) print('conv_out') show_conv_img(conv_out_val) # 池化後的圖像展現 pool_val = sess.run(max_pool) print('pool') show_conv_img(pool_val)
原始圖像 w參數 第一次卷積 激活後 池化後
第三部分:進行正式的圖像的訓練操做
第一步:使用tf.placeholder(tf.float32, shape=[None, 24*24]) tf.placeholder(tf.float32, shape=[None, len(names)]) # 構造x和y
第二步:構造卷積層和全鏈接層的參數
第一層卷積: w:5,5,1,64 b:64
第二層卷積: w: 5,5,64.64 b:64
第三層全鏈接: w: 6*6*64, 1024 b:1024
第四層全鏈接: w:1024,len(names) b:len(names)
第三步:構造conv函數:用於進行卷積,激活操做
第四步:構造pool函數:用於進行最大值池化操做
第五步:構造model函數:進行卷積和全鏈接操做
第一步:使用tf.reshape(x, [None, 28, 28, 1]) 進行矩陣的維度變化
第二步:進行第一次卷積和池化操做
第三步:使用tf.nn.lrn對數據進行局部最大值響應
第四步:進行第二次卷積操做
第五步:使用tf.nn.lrn對數據進行局部最大值響應
第六步:進行第二次池化操做
第七步:改變池化後的矩陣的維度,爲[-1, 6*6*64],進行第一次全鏈接操做
第八步:進行第二次全鏈接操做
第六步:將返回的model_op得分,使用tf.reduce_mean(tf.nn.softmax) 構造softmax的損失函數
第七步: 使用tf.nn.Adaoptimer() 自適應梯度降低來進行損失值得下降
第八步:使用tf.equal() 和 tf.reduce_mean 計算accur
第九步:構造sess執行函數,並進行初始化操做
第十步:使用tf.one_hot將標籤轉換爲one_hot格式,並使用sess.run將tf格式的標籤從新轉換爲數組格式
第十一步:進入循環,設置batch的大小,以及平均準確率爲0
第十二步:使用np.arange(0, len(data), batch_size) 進行一個batch的循環,使用data_batch = data[j:j+batch, :] 得到一個batch的數據,同理得到一個標籤的數據
第十三步:將batch數據帶入到sess.run([opt, accr]) 進行梯度降低和準確率的計算,
第十四步:計算平均準確率,並打印
#第三部分: 開始進行正式的模型訓練 # 第一步:使用tf.placeholder()進行輸入數據的初始化 x = tf.placeholder(tf.float32, [None, 24*24]) y = tf.placeholder(tf.float32, [None, len(names)]) # 第二步:構造卷積和全鏈接的參數 # W1的維度爲5,5,1, 64 W1 = tf.Variable(tf.random_normal([5, 5, 1, 64])) # b1的維度爲64 b1 = tf.Variable(tf.random_normal([64])) # W2的維度爲5,5,64,64 W2 = tf.Variable(tf.random_normal([5, 5, 64, 64])) # b2的維度爲64 b2 = tf.Variable(tf.random_normal([64])) # W3的維度爲6*6*64, 1024 W3 = tf.Variable(tf.random_normal([6*6*64, 1024])) # b3的維度爲64 b3 = tf.Variable(tf.random_normal([1024])) # W_out的維度爲1024,10 W_out = tf.Variable(tf.random_normal([1024, len(names)])) # b_out的維度爲10 b_out = tf.Variable(tf.random_normal([len(names)])) # 第三步:構建卷積和激活層的函數 def conv(x, w, b): return tf.nn.relu(tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') + b) # 第四步:構建池化層的函數 def pool(x, k=2): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # 第五步:構建模型,進行卷積和全鏈接的操做 def model(): # 進行輸入x的維度變換,以便進行後續的卷積操做 x_reshapedd = tf.reshape(x, shape=[-1, 24, 24, 1]) # 進行卷積操做 conv_h1 = conv(x_reshapedd, W1, b1) # 進行池化操做 pool_h1 = pool(conv_h1) # 進行非極大值抑制操做 norm1 = tf.nn.lrn(pool_h1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 進行第二次卷積操做 conv_h2 = conv(norm1, W2, b2) # 進行非極大值抑制操做 norm2 = tf.nn.lrn(conv_h2, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 進行池化操做 pool_h2 = pool(norm2) # 重構池化層後的矩陣維度,爲了進行全鏈接操做 fc1_input = tf.reshape(pool_h2, [-1, 6*6*64]) # 進行第一次全鏈接操做 fc_h1 = tf.nn.relu(tf.matmul(fc1_input, W3) + b3) # 進行第二次全鏈接操做 fc_out = tf.matmul(fc_h1, W_out) + b_out return fc_out # 第六步:得到得分,使用tf.nn.softmax_cross得到softmax的損失值 model_op = model() cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=model_op, labels=y)) # 第七步:使用自適應損失值優化器,進行損失值的降低 train_op = tf.train.AdamOptimizer(0.001).minimize(cost) # 第八步:使用tf.equal和tf.reduce_mean求出準確度 correct_pred = tf.equal(tf.argmax(model_op, 1), tf.argmax(y, 1)) accur = tf.reduce_mean(tf.cast(correct_pred, 'float')) batch_size = 50 # 第九步:構造sess,並進行初始化 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 第十步:對標籤使用one-hot編碼,並使用sess.run()轉換回數據類型 train_labels = tf.one_hot(labels, len(names), axis=-1) train_labels = sess.run(train_labels) for j in range(1000): # 第十一步:設置batchsize大小,即average的平均值爲0 average = 0 batch_num = 0 for i in range(0, len(data), batch_size): # 第十二步:使用data[i:i+batch_size, :] 得到batch數據和batch標籤值 train_data = data[i:i+batch_size, :] train_label = train_labels[i:i+batch_size, :] # 第十三步:將batch數據和標籤值帶入,用於進行損失值的下降和準確率的計算 _, accurracy = sess.run([train_op, accur], feed_dict={x:train_data, y:train_label}) average += accurracy batch_num += 1 # 第十四步:求出平均準確率並打印 average /= batch_num print('epoch average accurracy %g'%(average, ))
迭代的結果