深度学习之cifar-10⑥——十分类(cifar_10_inception)

这个代码与前面代码类似,只是用的模型不一样,这里运用的是inception模型,详情注释请看 深度学习之cifar-10④——十分类(cifar_10_Alexnet) 或 ⑤ 都一样

import tensorflow as tf
import os
import pickle
import numpy as np

cifar_dir = '../../datas/cifar-10-batches-py'

def load_data(filename):
    with open(filename,'rb') as f:
        data = pickle.load(f,encoding='bytes')
        return data[b'data'],data[b'labels']

class Cifar_Data:

    def __init__(self,filenames,need_shuffle):
        all_data = []
        all_labels = []

        for filename in filenames:
            data , labels = load_data(filename)
            all_data.append(data)
            all_labels.append(labels)

        self.data = np.vstack(all_data)
        self.data = self.data / 127.5 - 1
        self.labels = np.hstack(all_labels)

        print(self.data.shape)
        print(self.labels.shape)

        self.num_examples = self.data.shape[0]
        self.indicator = 0
        self.need_shuffle = need_shuffle

        if self.need_shuffle:
            self.shuffle_data()

    def shuffle_data(self):
        p = np.random.permutation(self.num_examples)
        self.data = self.data[p]
        self.labels = self.labels[p]

    def next_batch(self,batch_size):
        end_indicator = self.indicator + batch_size
        if end_indicator > self.num_examples:
            if self.need_shuffle:
                self.shuffle_data()
                self.indicator = 0
                end_indicator = batch_size
            else:
                raise Exception('没有更多的例子')

        if end_indicator > self.num_examples:
            raise Exception('批次大于所有例子')

        batch_data = self.data[self.indicator:end_indicator]
        batch_labels = self.labels[self.indicator:end_indicator]
        self.indicator = end_indicator
        return batch_data,batch_labels

train_filenames = [os.path.join(cifar_dir,'data_batch_%d'%i)for i in range(1,6)]
test_filenames = [os.path.join(cifar_dir,'test_batch')]

train_data = Cifar_Data(train_filenames,True)
test_data = Cifar_Data(test_filenames,False)

# inception 块  三层卷积  一个最大池化
def inception_block(x,output_path):
    conv1_1 = tf.layers.conv2d(x,output_path[0],(1,1),padding='same',activation=tf.nn.relu)
    conv3_3 = tf.layers.conv2d(x,output_path[1],(3,3),padding='same',activation=tf.nn.relu)
    conv5_5 = tf.layers.conv2d(x,output_path[2],(5,5),padding='same',activation=tf.nn.relu)
    max_pooling = tf.layers.max_pooling2d(x,(2,2),(2,2),padding='same')

    #获取池化和输入的维度
    max_pooling_shape = max_pooling.get_shape().as_list()[1:]
    input_shape = x.get_shape().as_list()[1:]

    # 算出宽 高的维度   用来给最大池化padding
    w_shape = (input_shape[0] - max_pooling_shape[0]) // 2
    h_shape = (input_shape[1] - max_pooling_shape[1]) // 2

    # 让池化层padding与卷积一样大
    pad_poolong = tf.pad(max_pooling,[
        [0,0],[w_shape,w_shape],[h_shape,h_shape],[0,0]
    ])

    # 把四层摞在一起
    concat_layers = tf.concat([conv1_1,conv3_3,conv5_5,pad_poolong],axis=3)

    return concat_layers

x = tf.placeholder(tf.float32,[None,3072])
x_img = tf.reshape(x,[-1,32,32,3])
y = tf.placeholder(tf.int64,[None])

# 一层卷积
conv1 = tf.layers.conv2d(x_img, 32, (3, 3), padding='same',activation=tf.nn.relu)
pooling1 = tf.layers.max_pooling2d(conv1,(2,2),(2,2),padding='same')

# 调用块  两次  并池化
inception_2a = inception_block(pooling1,[16,16,16])
inception_2b = inception_block(inception_2a,[16,16,16])
pooling2 = tf.layers.max_pooling2d(inception_2b,(2,2),(2,2),padding='same')

# 调用块  两次  并池化
inception_3a = inception_block(pooling2,[16,16,16])
inception_3b = inception_block(inception_3a,[16,16,16])
pooling3 = tf.layers.max_pooling2d(inception_3b,(2,2),(2,2),padding='same')

# 换化为向量
flatten = tf.layers.flatten(pooling3)

# 全连接
a = tf.layers.dense(flatten,10)

cost = tf.losses.sparse_softmax_cross_entropy(y,a)

optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)

pre = tf.argmax(a,1)
accuracy = tf.reduce_mean(tf.cast(tf.equal(pre,y),tf.float32))

sess = tf.Session()
sess.run(tf.global_variables_initializer())

# 长度
batch_size = 50

# 层数过多   只用了500for i in range(1,501):
    batch_x , batch_y = train_data.next_batch(batch_size)

    c,a,_ =sess.run([cost,accuracy,optimizer],feed_dict={x:batch_x,y:batch_y})

    if i % 100 == 0:
        print(i,c,a)

    if i % 250 == 0:
        batch_x1, batch_y1 = test_data.next_batch(batch_size)
        all_acc = []

        for k in range(1,101):
            a1 = sess.run(accuracy, feed_dict={x: batch_x1, y: batch_y1})
            all_acc.append(a1)
        print(np.mean(all_acc))

100 1.9033884 0.3
200 1.6314828 0.38
0.54
300 1.6455951 0.44
400 1.5996035 0.42
500 1.6855372 0.44
0.5
因为层数比较多,这里训练次数较少所以准确率较低

你可能感兴趣的:(深度学习之cifar-10⑥——十分类(cifar_10_inception))