1. 程式人生 > >北大人工智慧網課攻略[3]:cifar-10十種分類

北大人工智慧網課攻略[3]:cifar-10十種分類

北大人工智慧網課階段測試只有一個。在第七講中老師使用了lenet5網路進行了mnist手寫字型的識別,然後留了一個使用lenet5網路進行十種目標識別的測試。與之前識別手寫體最大的不同在於,我們無法使用原來老師的影象讀入方式,它不再是一個壓縮包下的一個檔案加一個壓縮包下的標籤資料。所以我們應該編寫讀入圖片形式的程式,並使用lenet5網路進行訓練與識別。 在成功地於Linux環境下使用百度雲下載好資料集後,我點開了幾張圖片。 在這裡插入圖片描述在這裡插入圖片描述 這感人的清晰度,不愧是32×32畫素,天若有情天亦老,我為cifar續一秒。 在這裡插入圖片描述 編寫讀入程式,命名為get_data.py:

import tensorflow as tf
import
numpy as np import os import math def get_files(file_dir): image_list = [] label_list= [] num = 0 for file in os.listdir(file_dir): filedir_f = file_dir + file for filedir_p in os.listdir(filedir_f): image_list.append(filedir_f + '/' +filedir_p) label_list.
append(num) num = num + 1 temp = np.array([image_list, label_list]) temp = temp.transpose() np.random.shuffle(temp) all_image_list = temp[:, 0] all_label_list = temp[:, 1] all_label_list = [int(float(i)) for i in all_label_list] print('There are %d image\n'
%(len(image_list))) return all_image_list,all_label_list def get_batch(image, label, image_W, image_H, batch_size, capacity): image = tf.cast(image, tf.string) label = tf.cast(label, tf.int32) # make an input queue input_queue = tf.train.slice_input_producer([image, label]) label = input_queue[1] image_contents = tf.read_file(input_queue[0]) image = tf.image.decode_jpeg(image_contents, channels=3) image = tf.image.resize_image_with_crop_or_pad(image, image_W, image_H) image = tf.image.per_image_standardization(image) image_batch, label_batch = tf.train.batch([image, label], batch_size= batch_size, num_threads= 64, capacity = capacity) label_batch = tf.reshape(label_batch, [batch_size]) image_batch = tf.cast(image_batch, tf.float32) return image_batch, label_batch

第一個子程式是獲取train或test目錄下的各種類資料夾下的圖片,並將資料夾名作為類別,再進行亂序。 第二個子程式是將輸入的圖片製作成batch,對於我的程式是25張圖片一批進行訓練。 按照lenet5網路編寫model.py:

import tensorflow as tf
def inference(images, batch_size, n_classes,keep_prob):  
    conv1 = tf.layers.conv2d(images,6,3,1,'valid',activation=tf.nn.relu)  
    pool1 = tf.layers.max_pooling2d(conv1, 2, 2)
    conv2 = tf.layers.conv2d(pool1, 16, 3, 1, 'valid', activation=tf.nn.relu)
    pool2 = tf.layers.max_pooling2d(conv2, 2, 2)
    reshape = tf.reshape(pool2, shape=[batch_size, -1])
    local3 = tf.layers.dense(reshape, 400)
    local4 = tf.layers.dense(local3, 400) 
    h_drop = tf.nn.dropout(local4, keep_prob)
    softmax_linear = tf.layers.dense(h_drop, n_classes)
    return softmax_linear
#%%
def losses(logits, labels):
    with tf.variable_scope('loss') as scope:
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits\
                        (logits=logits, labels=labels, name='xentropy_per_example')
        loss = tf.reduce_mean(cross_entropy, name='loss')
        tf.summary.scalar(scope.name+'/loss', loss)
    return loss
#%%
def trainning(loss, learning_rate):
    with tf.name_scope('optimizer'):
        optimizer = tf.train.AdamOptimizer(learning_rate= learning_rate)
        global_step = tf.Variable(0, name='global_step', trainable=False)
        train_op = optimizer.minimize(loss, global_step= global_step)
    return train_op
#%%
def evaluation(logits, labels):
  with tf.variable_scope('accuracy') as scope:
      correct = tf.nn.in_top_k(logits, labels, 1)
      correct = tf.cast(correct, tf.float16)
      accuracy = tf.reduce_mean(correct)
      tf.summary.scalar(scope.name+'/accuracy', accuracy)
  return accuracy

就是定義模型,損失,訓練,評估子函式。

最後是主函式,執行主函式進行訓練。

import os
import numpy as np
import tensorflow as tf
import get_data
import model
import matplotlib.pyplot as plt

N_CLASSES = 10	#類別
IMG_W = 32	#影象整合大小
IMG_H = 32
BATCH_SIZE = 25	#批次大小,一次25CAPACITY = 1000 #每批次最大容量
MAX_STEP = 100000 # 訓練總批次
VAL_SPACE = 100	#訓練幾批,測試一次
learning_rate = 0.0001 # 學習率

# 用這個程式,請改路徑
train_dir = '/home/emin/Temp/Tensorflow/cifar-10/train/' 
test_dir  = '/home/emin/Temp/Tensorflow/cifar-10/test/'
logs_train_dir = '/home/emin/Temp/Tensorflow/Me/cifar_me/train/'
logs_val_dir = '/home/emin/Temp/Tensorflow/Me/cifar_me/val/'
arra = [0]*(int(MAX_STEP/VAL_SPACE))#儲存訓練準確度
brra = [0]*(int(MAX_STEP/VAL_SPACE))#儲存測試準確度
train, train_label = get_data.get_files(train_dir)	#讀訓練集
val, val_label     = get_data.get_files(test_dir)	#讀測試集
train_batch, train_label_batch = get_data.get_batch(train,
                                              train_label,
                                              IMG_W,
                                              IMG_H,
                                              BATCH_SIZE, 
                                              CAPACITY)
val_batch, val_label_batch = get_data.get_batch(val,
                                              val_label,
                                              IMG_W,
                                              IMG_H,
                                              BATCH_SIZE, 
                                              CAPACITY)
							#生成批次
x = tf.placeholder(tf.float32, shape=[BATCH_SIZE, IMG_W, IMG_H, 3])
y_ = tf.placeholder(tf.int32, shape=[BATCH_SIZE])
keep_prob = tf.placeholder(tf.float32)			#損失率

logits = model.inference(x, BATCH_SIZE, N_CLASSES,keep_prob)
loss = model.losses(logits, y_)  			#計算誤差
acc = model.evaluation(logits, y_)			#計算準確度
train_op = model.trainning(loss, learning_rate)		#訓練開始程式
         
with tf.Session() as sess:
    saver = tf.train.Saver()				#執行佇列準備等
    sess.run(tf.global_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess= sess, coord=coord)
    summary_op = tf.summary.merge_all()        
    train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)
    val_writer = tf.summary.FileWriter(logs_val_dir, sess.graph)
    							#儲存訓練資訊
    try:
        for step in np.arange(MAX_STEP):
            if coord.should_stop():			#意外終止
                    break
            tra_images,tra_labels = sess.run([train_batch, train_label_batch])
            _, tra_loss, tra_acc = sess.run([train_op, loss, acc],
                                            feed_dict={x:tra_images, y_:tra_labels,keep_prob:0.5})
                                            		#訓練進行,並獲取準確度等
            if step % 10 == 0:
                print('Step %d, train loss = %.2f, train accuracy = %.2f%%' %(step, tra_loss, tra_acc*100.0))
                					#顯示每次訓練時準確度
            if step % VAL_SPACE == 0 or (step + 1) == MAX_STEP:
                val_images, val_labels = sess.run([val_batch, val_label_batch])
                val_loss, val_acc = sess.run([loss, acc], 
                                             feed_dict={x:val_images, y_:val_labels,keep_prob:1.0})
                print('**  Step %d, val loss = %.2f, val accuracy = %.2f%%  **' %(step, val_loss, val_acc*100.0))   
                					#每VAL_SPACE進行一次測試,顯示準確度等
                arra[int(step/VAL_SPACE)]=tra_acc*100
                brra[int(step/VAL_SPACE)]=val_acc*100	#儲存資料
            if step % 1000 == 0:    			#儲存訓練模型
                checkpoint_path = os.path.join(logs_train_dir, 'model.ckpt')
                saver.save(sess, checkpoint_path, global_step=step)
    except tf.errors.OutOfRangeError:
        print('Done training -- epoch limit reached')
    finally:
        coord.request_stop()           
    coord.join(threads)
    plt.plot(arra, c='blue')
    plt.show()
    plt.plot(brra, c='red')
    plt.show()						#出圖

最後結果測試和訓練準確度大概在65±15%,這種圖片訓練lenet5在我的破電腦上一小時能訓練成這樣已經很強了,竟然沒有多少過擬合,挺好。不過當時我的測試是每10批次進行一次,之後保留資料進行畫圖,總共一萬個點擠在一張10K的圖上,所以圖畫的非常難看。不貼了。