VGG网络结构
#pip install tflearn
from tflearn.datasets import oxflower17
import tensorflow as tf
#mnist oxflower17 cifar10 cifar100 图像有关数据
X,Y=oxflower17.load_data(one_hot=True) #下载oxflower17数据集
print(X.shape) #(1360, 224, 224, 3)
print(Y.shape) #(1360, 17)
#图像分类
#1.设计超参数
#(1)训练有关的参数
train_epoch =1000 #训练迭代次数(训练数据遍历完一次 算一次迭代)
batch_size = 10 #每个批次训练多少数据
lr=tf.placeholder(tf.float32) #动态学习率
display_epoch = 100 #没学习100次 进行一次评估
n_class = Y.shape[1]
x = tf.placeholder(tf.float32,[None,224,224,3])
y = tf.placeholder(tf.float32,[None,n_class])
#(2)网络有关的参数
weight={
'wc1_1':tf.Variable(tf.random_normal([3,3,3,64])), #3X3X3 64组 第一层卷积 => 224X224X64
'wc2_1':tf.Variable(tf.random_normal([3,3,64,128])), #3X3X64 128组 第二层卷积
'wc3_1':tf.Variable(tf.random_normal([3,3,128,256])), #3X3X128 256组 第三层卷积
'wc3_2':tf.Variable(tf.random_normal([3,3,256,256])), #3X3X256 256组 第三层卷积
'wc4_1':tf.Variable(tf.random_normal([3,3,256,512])), #3X3X256 256组 第三层卷积
'wc4_2':tf.Variable(tf.random_normal([3,3,512,512])), #3X3X256 256组 第三层卷积
'wc5_1':tf.Variable(tf.random_normal([3,3,512,512])), #3X3X256 256组 第三层卷积
'wc5_2':tf.Variable(tf.random_normal([3,3,512,512])), #3X3X256 256组 第三层卷积
'wfc_1':tf.Variable(tf.random_normal([7*7*512,4096])), #3X3X256 256组 第三层卷积
'wfc_2':tf.Variable(tf.random_normal([4096,4096])), #3X3X256 256组 第三层卷积
'wfc_3':tf.Variable(tf.random_normal([4096,n_class])), #3X3X256 256组 第三层卷积
}
biase={
'bc1_1':tf.Variable(tf.random_normal([64])), #3X3X3 64组 第一层卷积 => 224X224X64
'bc2_1':tf.Variable(tf.random_normal([128])), #3X3X64 128组 第二层卷积
'bc3_1':tf.Variable(tf.random_normal([256])), #3X3X128 256组 第三层卷积
'bc3_2':tf.Variable(tf.random_normal([256])), #3X3X256 256组 第三层卷积
'bc4_1':tf.Variable(tf.random_normal([512])), #3X3X256 256组 第三层卷积
'bc4_2':tf.Variable(tf.random_normal([512])), #3X3X256 256组 第三层卷积
'bc5_1':tf.Variable(tf.random_normal([512])), #3X3X256 256组 第三层卷积
'bc5_2':tf.Variable(tf.random_normal([512])), #3X3X256 256组 第三层卷积
'bfc_1':tf.Variable(tf.random_normal([4096])), #3X3X256 256组 第三层卷积
'bfc_2':tf.Variable(tf.random_normal([4096])), #3X3X256 256组 第三层卷积
'bfc_3':tf.Variable(tf.random_normal([n_class])), #3X3X256 256组 第三层卷积
}
#2.设计网络
def vgg_network():
#input 输入层的预处理
#conv1 第一层
#tf.nn.conv2d是TensorFlow里面实现卷积的函数,参考文档对它的介绍并不是很详细,实际上这是搭建卷积神经网络比较核心的一个方法,非常重要
#tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
#第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]
#这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一
#第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]
#这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维
#第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4
#第四个参数padding:string类型的量,只能是
#"SAME", "VALID"
#其中之一,这个值决定了不同的卷积方式(后面会介绍)
#第五个参数:use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true
#结果返回一个Tensor,这个输出,就是我们常说的feature
#map,shape仍然是[batch, height, width, channels]这种形式。
#===============================================第一层======================================
net = tf.nn.conv2d(input=x,filter=weight['wc1_1'],strides=[1,1,1,1],padding='SAME') #第一层卷积
print('covn',net)
net = tf.nn.leaky_relu(tf.nn.bias_add(net,biase['bc1_1'])) #激励函数
print('relu', net)
net = tf.nn.lrn(net) #局部归一化
print('lrn', net)
#
#ksize 窗口大小
#strides 步长 [batch, in_height, in_width, in_channels]
net = tf.nn.max_pool(value=net,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME') #池化
print('max_pool', net)
#===============================================第二层======================================
net = tf.nn.conv2d(net, filter=weight['wc2_1'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc2_1']))
net = tf.nn.max_pool(value=net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding='VALID') # 池化
print('max_pool', net)
# ===============================================第三层======================================
net = tf.nn.conv2d(net, filter=weight['wc3_1'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc3_1']))
net = tf.nn.conv2d(net, filter=weight['wc3_2'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc3_2']))
net = tf.nn.max_pool(value=net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding='VALID') # 池化
print('max_pool', net)
# ===============================================第四层======================================
net = tf.nn.conv2d(net, filter=weight['wc4_1'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc4_1']))
net = tf.nn.conv2d(net, filter=weight['wc4_2'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc4_2']))
net = tf.nn.max_pool(value=net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding='VALID') # 池化
print('max_pool', net)
# ===============================================第五层======================================
net = tf.nn.conv2d(net, filter=weight['wc5_1'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc5_1']))
net = tf.nn.conv2d(net, filter=weight['wc5_2'], strides=[1, 1, 1, 1],padding='SAME')
net = tf.nn.leaky_relu(tf.nn.bias_add(net, biase['bc5_2']))
net = tf.nn.max_pool(value=net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding='VALID') # 池化
print('max_pool', net)
# 拉伸,开始全连接层 7X7X512
net = tf.reshape(net, shape=[-1, weight['wfc_1'].get_shape()[0]])
#全连接(BP网络)
net = tf.matmul(net,weight['wfc_1'])+biase['bfc_1']
net = tf.nn.relu(net)
net = tf.matmul(net, weight['wfc_2']) + biase['bfc_2']
net = tf.nn.relu(net)
# out层
return tf.matmul(net, weight['wfc_3']) + biase['bfc_3']
#3.设计损失函数和优化器,建立评估函数 (正确率)
pred = vgg_network()
loss = tf.nn.softmax_cross_entropy_with_logits(logits = pred,labels = y) #损失函数
#tf.nn.sigmoid_cross_entropy_with_logits()
opt = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(loss) #梯度下降学习(优化器)
#one_hot 17位
#【true.false】 选出true的值
acc_tf = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
acc = tf.reduce_mean(tf.cast(acc_tf,tf.float32)) #平均值
#4.训练
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) #初始化全局变量,相当于给上面的变量进行赋值
base_lr = 0.01 #初始学习率
learning_rate = base_lr
for epoch in range(train_epoch): #1000次迭代
# batch_size =10,total_data =1360
# 取数据
total_batch = X.shape[0] // batch_size # 计算一次迭代需要多少批数据
for i in range(total_batch):
X_train, Y_train = X[i * batch_size:i * batch_size + batch_size], Y[i * batch_size:i * batch_size + batch_size]
print('step:%s' % str(epoch) + '-' + str(i))
sess.run(opt, feed_dict={x: X_train, y: Y_train,lr:learning_rate})
if (i + 1) * (epoch + 1) % display_epoch == 0:
#进行评估
cost,accuaray = sess.run([loss,acc],feed_dict={x: X_train, y: Y_train,lr:learning_rate})
print('step:%s,loss:%f,acc:%f'%str(epoch)+"-"+str(i),cost,accuaray)
# 动态学习率设置。
learning_rate = base_lr * ((1 - epoch) / train_epoch) ** 2