Cifar-10影象分類任務
Cifar-10資料集
Cifar-10資料集是由10類32*32的彩色圖片組成的資料集,一共有60000張圖片,每類包含6000張圖片。其中50000張是訓練集,1000張是測試集。
1. 獲取每個batch檔案中的字典資訊
import pickle
def unpickle(file):
fo = open(file,'rb')
dick = pickle.load(fo,encoding='latin1')
fo.close()
return dick
在字典結構中,每一張圖片是以被展開的形式儲存,即一張32*32*3的圖片被展開成3072長度的list,每一個數據的格式為unit8,前1024為紅色通道,中間1024為綠色通道,後1024為藍色通道。
2.影象預處理。對資料進行標準化操作,按照一定比例進行縮放,使其落入一個特定的區域,便於操作處理。提高了處理速度。
import numpy as np def clean(data): imgs = data.reshape(data.shape[0],3,32,32) grayscale_imgs = imgs.mean(1) cropped_imgs = grayscale_imgs[:,4:28,4:28] img_data = cropped_imgs.reshape(data.shape[0],-1) img_size = np.shape(img_data)[1] means = np.mean(img_data,axis=1) meansT = means.reshape(len(means),1) stds = np.std(img_data,axis=1) stdsT = stds.reshape(len(stds),1) adj_stds = np.maximum(stdsT,1.0/np.sqrt(img_size)) normalized = (img_data - meansT) / adj_stds return normalized
mean(axis)函式:求平均值。對m*n的矩陣來說
axis=0:壓縮行,對各列求平均值,返回1*n矩陣。
axis=1:壓縮列,對各行求平均值,返回m*1矩陣。
axis不設定值,對m*n個數求平均值,返回一個實數。
reshape()函式:改變陣列的形狀。
reshape((2,4)):變為一個二維陣列;reshape((2,2,2)):變為一個三維陣列
當有一個引數為-1時,會根據另一個引數的維度計算陣列的另外一個shape屬性值。
如reshape(data.shape[0],-1):行為data.shape[0]行,列自動算出。data.shape[0]:data第一維的長度。
3.影象資料讀取
def read_data(directory):
names = unpickle('{}/batches.meta'.format(directory))['label_names']
print('dede')
print('names',names)
print('dede')
data,labels = [],[]
#一個batch一個batch的去讀取batch資料
for i in range(1,6):
filename = '{}/data_batch_{}'.format(directory,i)
batch_data = unpickle(filename)
#拼加操作
if len(data) > 0:
data = np.vstack((data,batch_data['data']))
labels = np.hstack((labels,batch_data['labels']))
else:
data = batch_data['data']
labels = batch_data['labels']
print('haha')
print(np.shape(data),np.shape(labels)) #輸出data和labels的長度
print('haha')
data = clean(data)
data = data.astype(np.float32)
return names,data,labels
下圖為names的值,圖片集中的分類
可以看出,data和labels的資料型別為ndarray,batch_data的資料型別為字典型別。
hstack(a,b,c,d):水平把陣列堆疊起來
vstack(a,b,c,d):豎直把陣列堆疊起來
4.顯示資料
import matplotlib.pyplot as plt
import random
random.seed(1)
#把資料讀取進來
names,data,labels = read_data('D://hh/cifar-10-batches-py')
def show_some_examples(names,data,labels):
plt.figure()
#繪製一個子圖 4*4結構
rows,cols = 4,4
random_idxs = random.sample(range(len(data)),rows * cols)
for i in range(rows*cols):
plt.subplot(rows,cols,i+1)
j = random_idxs[i]
plt.title(names[labels[j]])
img = np.reshape(data[j,:],(24,24))
plt.imshow(img,cmap='Greys_r')
plt.axis('off')
plt.tight_layout()
plt.savefig('cifar_examples,png')
show_some_examples(names,data,labels)
print('stop1')
繪製的圖
5.經過卷積後的結果
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
names,data,labels = read_data('D://hh/cifar-10-batches-py')
def show_conv_results(data,filename = None):
plt.figure()
#子圖 4行8列 每一個子圖都是其中的一個特徵圖
rows,cols = 4,8
for i in range(np.shape(data)[3]):
img = data[0,:,:,i] #分別取當前的每一個特徵圖
plt.subplot(rows,cols,i+1)
plt.imshow(img,cmap='Greys_r',interpolation='none')
plt.axis('off')
if filename:
plt.savefig(filename)
else:
plt.show()
print('stop2')
#權重引數
def show_weights(W,filename=None):
plt.figure()
rows,cols = 4,8
for i in range(np.shape(W)[3]):
img = W[:,:,0,i]
plt.subplot(rows,cols,i+1)
plt.imshow(img,cmap='Greys_r',interpolation='none')
plt.axis('off')
if filename:
plt.savefig(filename)
else:
plt.show()
#顯示
raw_data = data[4,:]
raw_img = np.reshape(raw_data,(24,24))
plt.figure()
plt.imshow(raw_img,cmap='Greys_r')
plt.show()
6.引數設定
x = tf.reshape(raw_data,shape=[-1,24,24,1])
W = tf.Variable(tf.random_normal([5,5,1,32])) #輸入為1 輸出為32
b = tf.Variable(tf.random_normal([32]))
7.卷積操作
conv = tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME') #卷積
conv_with_b = tf.nn.bias_add(conv,b) #卷積後加偏置項
conv_out = tf.nn.relu(conv_with_b) #啟用函式
k = 2
maxpool = tf.nn.max_pool(conv_out,ksize=[1,k,k,1],strides=[1,k,k,1], padding='SAME')
8.檢視中間結果
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
W_val = sess.run(W)
print('weight:')
show_weights(W_val)
#開始卷積
conv_val = sess.run(conv)
print("convolution results:")
print(np.shape(conv_val))
show_conv_results(conv_val)
#relu
conv_out_val = sess.run(conv_out)
print("convolution with blas and relu:")
print(np.shape(conv_out_val))
show_conv_results(conv_out_val)
#池化
maxpool_val = sess.run(maxpool)
print("maxpool after all the convolutions:")
print(np.shape(maxpool_val))
show_conv_results(maxpool_val)
weight:
卷積:
relu:
最大池化:
9.構建網路模型
x = tf.placeholder(tf.float32,[None,24*24])
y = tf.placeholder(tf.float32,[None,len(names)])
W1 = tf.Variable(tf.random_normal([5,5,1,64]))
b1 = tf.Variable(tf.random_normal([64]))
W2 = tf.Variable(tf.random_normal([5,5,64,64]))
b2 = tf.Variable(tf.random_normal([64]))
W3 = tf.Variable(tf.random_normal([6*6*64,1024]))
b3 = tf.Variable(tf.random_normal([1024]))
W_out = tf.Variable(tf.random_normal([1024,len(names)]))
b_out = tf.Variable(tf.random_normal([len(names)]))
10.卷積池化操作函式
def conv_layer(x,W,b):
conv = tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
conv_with_b = tf.nn.bias_add(conv,b)
conv_out = tf.nn.relu(conv_with_b)
return conv_out
def maxpool_layer(conv,k=2):
return tf.nn.max_pool(conv,ksize=[1,k,k,1],strides=[1,k,k,1],padding='SAME')
11.把引數組合到一起
def model():
x_reshapes = tf.reshape(x,shape=[-1,24,24,1])
#卷積層
conv_out1 = conv_layer(x_reshapes,W1,b1)
#池化層
maxpool_out1 = maxpool_layer(conv_out1)
#提出了LRN層(區域性響應層),對區域性神經元的活動建立競爭機制,使得其中響應比較大的值變得相對更大,並抑制其他反饋比較小的神經元,
#增強了模型的泛化能力,使表達能力增強
norm1 = tf.nn.lrn(maxpool_out1,4,bias=1.0,alpha=0.001/9.0,beta=0.75)
#第二次卷積池化
conv_out2 = conv_layer(norm1,W2,b2)
norm2 = tf.nn.lrn(conv_out2,4,bias=1.0,alpha=0.01/9.0,beta=0.75)
maxpool_out2 = maxpool_layer(norm2)
maxpool_reshaped = tf.reshape(maxpool_out2,[-1,W3.get_shape().as_list()[0]])
local = tf.add(tf.matmul(maxpool_reshaped,W3),b3)
local_out = tf.nn.relu(local)
out = tf.add(tf.matmul(local_out,W_out),b_out)
return out
12. 指定學習率和 損失函式
learning_rate = 0.001
model_op = model()
cost = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(logits=model_op,labels=y)
)
train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
correct_pred = tf.equal(tf.argmax(model_op,1),tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
13.迭代
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#把標籤轉換成10個概率
onehot_labels = tf.one_hot(labels,len(names),axis=-1)
onehot_vals = sess.run(onehot_labels)
batch_size = 64
print('batch size',batch_size)
for j in range(0,1000):
avg_accuracy_val = 0
batch_count = 0
for i in range(0,len(data),batch_size):
batch_data = data[i:i+batch_size,:]
batch_onehot_vals = onehot_vals[i:i+batch_size,:]
_,accuracy_val = sess.run([train_op,accuracy],feed_dict={x:batch_data,y:batch_onehot_vals})
avg_accuracy_val += accuracy_val
batch_count += 1
avg_accuracy_val /= batch_count
print('Epoch[],Avg accuracy []',format(j,avg_accuracy_val))
print('Epoch [],Avg accuracy []',format(j,avg_accuracy_val))