基于tensorflow搭建一個復雜卷積神經網絡模型(cifar-10)

上一篇搭建了一個簡單的cnn網絡用來識別手寫數字。

基于tensorflow搭建一個簡單的CNN模型(code)

這次我們將要搭建一個較復雜的卷積神經網絡結構去對CIFAR-10進行訓練和識別。

1. load 一些必要的庫和 start a graph session:

import os

import sys

import tarfile

import matplotlib.pyplot as plt

import numpy as np


import tensorflow as tf

from six.moves import urllib

sess = tf. Session()

2. 定義一些模型參數

batch_size = 128

output_every = 50

generations = 20000

eval_every = 500

image_height = 32

image_width = 32

crop_height = 24

crop_width = 24

num_channels = 3

num_targets = 10

data_dir = 'temp'

extract_folder = 'cifar-10-batches-bin'

3. 定義訓練學習率等幾個參數

learning_rate = 0.1

lr_decay = 0.9

num_gens_to_wait = 250

4. 現在我們建立可以讀取二進制 CIFAR-10圖片的參數

image_vec_length = image_height * image_width * num_channels

record_length = 1 + image_vec_length

5. 建立數據的路徑及下載CIFAR-10數據集圖片

data_dir = 'temp'

if not os.path.exists(data_dir):

? ? os.makedirs(data_dir)

? ? cifar10_url = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'

? ? data_file = os.path.join(data_dir, 'cifar-10-binary.tar.gz')

if not os.path.isfile(data_file):

? ? # Download file

? ? filepath, _ = urllib.request.urlretrieve(cifar10_url, data_file, progress)

? ? # Extract file

? ? tarfile.open(filepath, 'r:gz').extractall(data_dir)

6. 建立函數讀取隨機扭曲的圖片

def read_cifar_files(filename_queue, distort_images = True):

? ? reader = tf.FixedLengthRecordReader(record_bytes=record_length)

? ? key, record_string = reader.read(filename_queue)

? ? record_bytes = tf.decode_raw(record_string, tf.uint8)

? ? # Extract label

? ? image_label = tf.cast(tf.slice(record_bytes, [0], [1]),

? ? tf.int32)

? ? # Extract image

? ? image_extracted = tf.reshape(tf.slice(record_bytes, [1],

? ? [image_vec_length]), [num_channels, image_height, image_width])

? ? # Reshape image

? ? image_uint8image = tf.transpose(image_extracted, [1, 2, 0])

? ? reshaped_image = tf.cast(image_uint8image, tf.float32)

? ? # Randomly Crop image

? ? final_image = tf.image.resize_image_with_crop_or_pad(reshaped_

? ? image, crop_width, crop_height)

? ? if distort_images:

? ? ? ? # Randomly flip the image horizontally, change the brightness and contrast

? ? ? ? final_image = tf.image.random_flip_left_right(final_image)

? ? ? ? final_image = tf.image.random_brightness(final_image,max_delta=63)

? ? ? ? final_image = tf.image.random_contrast(final_

? ? ? ? image,lower=0.2, upper=1.8)

? ? # Normalize whitening

注意## For anyone else who has this problem, per_image_whitening was ? ? ? ? replaced by per_image_standardization

? ? # final_image = tf.image.per_image_whitening(final_image)

? ? final_image = tf.image.per_image_standardization(final_image)

? ? return(final_image, image_label)

## by per_image_standardization in v0.12


## For anyone else who has this problem, per_image_whitening was replaced

## by per_image_standardization in v0.12

final_image = tf.image.per_image_standardization(final_image)

7. 定義一個函數傳入數據

def input_pipeline(batch_size, train_logical=True):

? ? if train_logical:

? ? ? ? files = [os.path.join(data_dir, extract_folder, 'data_

? ? ? ? batch_{}.bin'.format(i)) for i in range(1,6)]

? ? else:

? ? ? ? files = [os.path.join(data_dir, extract_folder, 'test_batch.bin')]

? ? filename_queue = tf.train.string_input_producer(files)

? ? image, label = read_cifar_files(filename_queue)

? ? min_after_dequeue = 1000

? ? capacity = min_after_dequeue + 3 * batch_size

? ? example_batch, label_batch = tf.train.shuffle_batch([image,

? ? label], batch_size, capacity, min_after_dequeue)

? ? return(example_batch, label_batch)

8. 定義模型

# Define the model architecture, this will return logits from images

def cifar_cnn_model(input_images, batch_size, train_logical=True):

? ? def truncated_normal_var(name, shape, dtype):

? ? ? ? ?return(tf.get_variable(name=name, shape=shape, dtype=dtype, ? ? ? ? initializer=tf.truncated_normal_initializer(stddev=0.05)))

? ? def zero_var(name, shape, dtype):

? ? ? ? ?return(tf.get_variable(name=name, shape=shape, dtype=dtype, initializer=tf.constant_initializer(0.0)))

? ? ? ? ?# First Convolutional Layer

? ? with tf.variable_scope('conv1') as scope:

? ? ? ? ? # Conv_kernel is 5x5 for all 3 colors and we will create 64 features

? ? ? ? ?conv1_kernel = truncated_normal_var(name='conv_kernel1', shape=[5, 5, 3, 64], dtype=tf.float32)

? ? ? ? ?# We convolve across the image with a stride size of 1

? ? ? ? ?conv1 = tf.nn.conv2d(input_images, conv1_kernel, [1, 1, 1, 1], padding='SAME')

? ? ? ? ?# Initialize and add the bias term

? ? ? ? ?conv1_bias = zero_var(name='conv_bias1', shape=[64], dtype=tf.float32)

? ? ? ? ?conv1_add_bias = tf.nn.bias_add(conv1, conv1_bias)

? ? ? ? ?# ReLU element wise

? ? ? ? ?relu_conv1 = tf.nn.relu(conv1_add_bias)

? ? ? ? ?# Max Pooling

? ? ? ? ?pool1 = tf.nn.max_pool(relu_conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1],padding='SAME', name='pool_layer1')

? ? ? ? ?# Local Response Normalization (parameters from paper)

? ? ? ? ?# paper: http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks

? ? ? ? ?norm1 = tf.nn.lrn(pool1, depth_radius=5, bias=2.0, alpha=1e-3, beta=0.75, name='norm1')

? ? ? ? ?# Second Convolutional Layer

? ? with tf.variable_scope('conv2') as scope:

? ? ? ? ?# Conv kernel is 5x5, across all prior 64 features and we create 64 more features

? ? ? ? ?conv2_kernel = truncated_normal_var(name='conv_kernel2', shape=[5, 5, 64, 64], dtype=tf.float32)

? ? ? ? ?# Convolve filter across prior output with stride size of 1

? ? ? ? ?conv2 = tf.nn.conv2d(norm1, conv2_kernel, [1, 1, 1, 1], padding='SAME')

? ? ? ? ?# Initialize and add the bias

? ? ? ? ?conv2_bias = zero_var(name='conv_bias2', shape=[64], dtype=tf.float32)

? ? ? ? ?conv2_add_bias = tf.nn.bias_add(conv2, conv2_bias)

? ? ? ? ?# ReLU element wise

? ? ? ? ?relu_conv2 = tf.nn.relu(conv2_add_bias)

? ? ? ? ?# Max Pooling

? ? ? ? ?pool2 = tf.nn.max_pool(relu_conv2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], ? ? ? ? ? padding='SAME', name='pool_layer2')

? ? ? ? ?# Local Response Normalization (parameters from paper)

? ? ? ? ?norm2 = tf.nn.lrn(pool2, depth_radius=5, bias=2.0, alpha=1e-3, beta=0.75, name='norm2')

? ? ? ? ?# Reshape output into a single matrix for multiplication for the fully connected layers

? ? ? ? ?reshaped_output = tf.reshape(norm2, [batch_size, -1])

? ? ? ? ?reshaped_dim = reshaped_output.get_shape()[1].value

? ? ? ? ?# First Fully Connected Layer

? ? with tf.variable_scope('full1') as scope:

? ? ? ? # Fully connected layer will have 384 outputs.

? ? ? ? full_weight1 = truncated_normal_var(name='full_mult1', shape=[reshaped_dim, 384], dtype=tf.float32)

? ? ? ? full_bias1 = zero_var(name='full_bias1', shape=[384], dtype=tf.float32)

? ? ? ? full_layer1 = tf.nn.relu(tf.add(tf.matmul(reshaped_output, full_weight1), full_bias1))

? ? ? ? # Second Fully Connected Layer

? ? with tf.variable_scope('full2') as scope:

? ? ? ? # Second fully connected layer has 192 outputs.

? ? ? ? full_weight2 = truncated_normal_var(name='full_mult2', shape=[384, 192], dtype=tf.float32)

? ? ? ? full_bias2 = zero_var(name='full_bias2', shape=[192], dtype=tf.float32)

? ? ? ? full_layer2 = tf.nn.relu(tf.add(tf.matmul(full_layer1, full_weight2), full_bias2))

? ? ? ? # Final Fully Connected Layer -> 10 categories for output (num_targets)

? ? with tf.variable_scope('full3') as scope:

? ? ? ? # Final fully connected layer has 10 (num_targets) outputs.

? ? ? ? full_weight3 = truncated_normal_var(name='full_mult3', shape=[192, ? ? ? num_targets], dtype=tf.float32)

? ? ? ? full_bias3 =? zero_var(name='full_bias3', shape=[num_targets], dtype=tf.float32)

? ? ? ? final_output = tf.add(tf.matmul(full_layer2, full_weight3), full_bias3)

? ? ? ? return(final_output)

9. ?定義loss函數

def cifar_loss(logits, targets):

? ? # Get rid of extra dimensions and cast targets into integers

? ? targets = tf.squeeze(tf.cast(targets, tf.int32))

? ? # Calculate cross entropy from logits and targets

? ? cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=targets)

? ? # Take the average loss across batch size

? ? cross_entropy_mean = tf.reduce_mean(cross_entropy)

? ? return(cross_entropy_mean)

10.定義訓練,其中學習率將要以指數下降。

def train_step(loss_value, generation_num):

? ? # Our learning rate is an exponential decay (stepped down)

? ? model_learning_rate = tf.train.exponential_decay(learning_rate, generation_num, num_gens_to_wait, lr_decay, staircase=True)

? ? # Create optimizer

? ? my_optimizer = tf.train.GradientDescentOptimizer(model_learning_rate)

? ? # Initialize train step

? ? train_step = my_optimizer.minimize(loss_value)

? ? return(train_step)

11. 計算準確率

def accuracy_of_batch(logits, targets):

? ? # Make sure targets are integers and drop extra dimensions

? ? targets = tf.squeeze(tf.cast(targets, tf.int32))

? ? # Get predicted values by finding which logit is the greatest

? ? batch_predictions = tf.cast(tf.argmax(logits, 1), tf.int32)

? ? # Check if they are equal across the batch

? ? predicted_correctly = tf.equal(batch_predictions, targets)

? ? # Average the 1's and 0's (True's and False's) across the batch size

? ? accuracy = tf.reduce_mean(tf.cast(predicted_correctly, tf.float32))

? ? return(accuracy)

12.輸入圖片

images, targets = input_pipeline(batch_size, train_logical=True)

test_images, test_targets = input_pipeline(batch_size, train_logical=False)

13. 聲明訓練模型和測試時模型用同樣的變量

with tf.variable_scope('model_definition') as scope:

? ? # Declare the training network model

? ? model_output = cifar_cnn_model(images, batch_size)

? ? # Use same variables within scope

? ? scope.reuse_variables()

? ? # Declare test model output

? ? test_output = cifar_cnn_model(test_images, batch_size)

14.初始化loss和測試精度函數

loss = cifar_loss(model_output, targets)

accuracy = accuracy_of_batch(test_output, test_targets)

generation_num = tf.Variable(0, trainable=False)

train_op = train_step(loss, generation_num)

15. 初始化網絡的所有變量

# Initialize Variables

print('Initializing the Variables.')

init = tf.initialize_all_variables()

sess.run(init)

# Initialize queue (This queue will feed into the model, so no placeholders necessary)

tf.train.start_queue_runners(sess=sess)

16. 迭代訓練,保存loss和測試accuracy

# Train CIFAR Model

print('Starting Training')

train_loss = []

test_accuracy = []

for i in range(generations):

? ? _, loss_value = sess.run([train_op, loss])

? ? if (i+1) % output_every == 0:

? ? ? ? train_loss.append(loss_value)

? ? ? ? output = 'Generation {}: Loss = {:.5f}'.format((i+1), loss_value)

? ? ? ? print(output)

? ? if (i+1) % eval_every == 0:

? ? ? ? [temp_accuracy] = sess.run([accuracy])

? ? ? ? test_accuracy.append(temp_accuracy)

? ? ? ? acc_output = ' --- Test Accuracy = {:.2f}%.'.format(100.*temp_accuracy)

? ? ? ? print(acc_output)


17.使用 matplotlib 講loss和測試accuracy圖像輸出來

# Print loss and accuracy

# Matlotlib code to plot the loss and accuracies

eval_indices = range(0, generations, eval_every)

output_indices = range(0, generations, output_every)

# Plot loss over time

plt.plot(output_indices, train_loss, 'k-')

plt.title('Softmax Loss per Generation')

plt.xlabel('Generation')

plt.ylabel('Softmax Loss')

plt.show()

# Plot accuracy over time

plt.plot(eval_indices, test_accuracy, 'k-')

plt.title('Test Accuracy')

plt.xlabel('Generation')

plt.ylabel('Accuracy')

plt.show()

在CIFAR-10的識別結果,左圖是訓練loss,右圖是test accuracy
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內容