参考了网上的一些vgg tensorflow 的代码,然后自己搭了一个网络。然后用这个网络来进行四种花的分类,训练了150代后,分类成功率竟然只有26%,也就比猜稍微高了一点点吧。而且到最后权重基本上就不变化了。回头尝试加一下batch_norm来试试看吧。可能是我迭代的次数少,vgg收敛比较慢,又或者是过拟合了吧。
vgg_net.py
import numpy as np
import tensorflow as tf
import read_picture
def cov_op(name,input,sw,sh,dw,dh,nout):
indim=input.get_shape()[-1].value
with tf.name_scope(name) as scope:
kernel=tf.get_variable(scope+"w",[3,3,indim,nout],
tf.float32,
initializer=tf.contrib.layers.xavier_initializer_conv2d())
l2_loss=tf.multiply(tf.nn.l2_loss(kernel),0.00005)
tf.add_to_collection('loss', l2_loss)
cov=tf.nn.conv2d(input,kernel,strides=[1,dw,dh,1],padding='SAME')
#biases=tf.get_variable('biases',shape=[nout],dtype=tf.float32,
# initializer=tf.contrib.layers.xavier_initializer_conv2d())
biases = tf.constant(0.0, shape=[nout], dtype=tf.float32)
tp=tf.nn.bias_add(cov,biases)
activation=tf.nn.relu(tp)
return activation
def pool_op(name,input,sw,sh,dw,dh):
with tf.name_scope(name) as scope:
return tf.nn.max_pool(input,[1,sw,sh,1],strides=[1,dw,dh,1],padding='SAME',name=name)
def fc_op(name,input,nout):
indim = input.get_shape()[-1].value
with tf.name_scope(name) as scope:
kernel=tf.get_variable(name+"w",shape=[indim,nout],dtype=tf.float32,
initializer=tf.contrib.layers.xavier_initializer_conv2d())
l2_loss = tf.multiply(tf.nn.l2_loss(kernel), 0.00005)
tf.add_to_collection('loss',l2_loss)
biases=tf.Variable(tf.constant(0.1,dtype=tf.float32,shape=[nout]))
tp=tf.nn.bias_add(tf.matmul(input,kernel),biases)
activation=tf.nn.relu(tp)
return activation
def inference(input,labels, keep_prob):
cov1_1=cov_op("cov1_1",input,3,3,1,1,64)
cov1_2=cov_op("cov1_2",cov1_1,3,3,1,1,64)
pool1=pool_op("pool1",cov1_2,2,2,2,2)
cov2_1=cov_op("cov2_1",pool1,3,3,1,1,128)
cov2_2=cov_op("cov2_2",cov2_1,3,3,1,1,128)
pool2=pool_op("pool2",cov2_2,2,2,2,2)
cov3_1=cov_op("cov3_1",pool2,3,3,1,1,256)
cov3_2=cov_op("cov3_2",cov3_1,3,3,1,1,256)
cov3_3 = cov_op("cov3_3", cov3_2, 3, 3, 1, 1, 256)
pool3=pool_op("pool3",cov3_3,2,2,2,2)
cov4_1=cov_op("cov4_1",pool3,3,3,1,1,512)
cov4_2=cov_op("cov4_2",cov4_1,3,3,1,1,512)
cov4_3 =cov_op("cov4_3", cov4_2, 3, 3, 1, 1, 512)
pool4=pool_op("pool4",cov4_3,2,2,2,2)
cov5_1=cov_op("cov5_1",pool4,3,3,1,1,512)
cov5_2=cov_op("cov5_2",cov5_1,3,3,1,1,512)
cov5_3 =cov_op("cov5_3", cov5_2, 3, 3, 1, 1, 512)
pool5=pool_op("pool5",cov5_3,2,2,2,2)
shp = pool5.get_shape()
dim=shp[1].value*shp[2].value*shp[3].value
pool5_flat=tf.reshape(pool5,shape=[-1,dim],name="finput")
fc6=fc_op("fc6",pool5_flat,4096)
fc6_dropout=tf.nn.dropout(fc6,keep_prob=keep_prob,name="fc6_dropout")
fc7=fc_op("fc7",fc6_dropout,4096)
fc7_dropout=tf.nn.dropout(fc7,keep_prob=keep_prob,name="fc7_dropput")
fc8=fc_op("fc8",fc7_dropout,4)
fc8_dropout=tf.nn.dropout(fc8,keep_prob=keep_prob,name="fc8_dropout")
softmax=tf.nn.softmax(fc8_dropout)
cross_entropy=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=fc8_dropout,labels=labels))
tf.add_to_collection('loss',(cross_entropy))
loss=tf.add_n(tf.get_collection('loss'))
train_op=tf.train.AdamOptimizer(0.005).minimize(loss)
return train_op,softmax,cross_entropy
batch_size=128
images_train, labels_train,images_test, labels_test= read_picture.create_batch(batch_size=batch_size,ratio=0.7)
keep_prob=tf.placeholder(tf.float32)
input=tf.placeholder(dtype=tf.float32,shape=[batch_size,24,24,3])
labels=tf.placeholder(dtype=tf.int64,shape=[batch_size])
train_op,softmax,cross_entropy=inference(input,labels, keep_prob)
accuracy=tf.reduce_mean(tf.cast(tf.equal(labels,tf.argmax(softmax,1)),tf.float32))
init_op=tf.initialize_all_variables()
sess=tf.InteractiveSession()
saver=tf.train.Saver()
init_op.run()
tf.train.start_queue_runners()
for i in range(300):
images_batch,labels_batch=sess.run([images_train,labels_train])
sess.run([train_op],feed_dict={input:images_batch,labels:labels_batch,keep_prob:0.5})
if i%1==0:
images_batch, labels_batch = sess.run([images_test, labels_test])
#sess.run(accuracy,feed_dict={input:images_batch,labels:labels_batch,keep_prob:1})
#lossvalue=sess.run([cross_entropy],feed_dict={input:images_batch,labels:labels_batch,keep_prob:1})
lossvalue = sess.run([accuracy], feed_dict={input: images_batch, labels: labels_batch, keep_prob: 1})
#print("step %d: loss is %f"%(i,lossvalue))
print(lossvalue)
read_picture.py (用于读入图片)
import os
import math
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
train_dir = 'E:\\test\\flower_photos'
daisy = []
label_daisy = []
dandelion = []
label_dandelion = []
roses = []
label_roses = []
sunflowers = []
label_sunflowers = []
# step1:获取'E:/Re_train/image_data/training_image'下所有的图片路径名,存放到
# 对应的列表中,同时贴上标签,存放到label列表中。
def get_files(file_dir, ratio):
for file in os.listdir(file_dir + '/daisy'):
daisy.append(file_dir + '/daisy' + '/' + file)
label_daisy.append(0)
for file in os.listdir(file_dir + '/dandelion'):
dandelion.append(file_dir + '/dandelion' + '/' + file)
label_dandelion.append(1)
for file in os.listdir(file_dir + '/roses'):
roses.append(file_dir + '/roses' + '/' + file)
label_roses.append(2)
for file in os.listdir(file_dir + '/sunflowers'):
sunflowers.append(file_dir + '/sunflowers' + '/' + file)
label_sunflowers.append(3)
# step2:对生成的图片路径和标签List做打乱处理把cat和dog合起来组成一个list(img和lab)
image_list = np.hstack((daisy, dandelion, roses, sunflowers))
label_list = np.hstack((label_daisy, label_dandelion, label_roses, label_sunflowers))
# 利用shuffle打乱顺序
temp = np.array([image_list, label_list])
temp = temp.transpose()
np.random.shuffle(temp)
# 从打乱的temp中再取出list(img和lab)
# image_list = list(temp[:, 0])
# label_list = list(temp[:, 1])
# label_list = [int(i) for i in label_list]
# return image_list, label_list
# 将所有的img和lab转换成list
all_image_list = list(temp[:, 0])
all_label_list = list(temp[:, 1])
# 将所得List分为两部分,一部分用来训练tra,一部分用来测试val
# ratio是测试集的比例
n_sample = len(all_label_list)
n_val = int(math.ceil(n_sample * ratio)) # 测试样本数
n_train = n_sample - n_val # 训练样本数
tra_images = all_image_list[0:n_train]
tra_labels = all_label_list[0:n_train]
tra_labels = [int(float(i)) for i in tra_labels]
val_images = all_image_list[n_train:-1]
val_labels = all_label_list[n_train:-1]
val_labels = [int(float(i)) for i in val_labels]
return tra_images, tra_labels, val_images, val_labels
# ---------------------------------------------------------------------------
# --------------------生成Batch----------------------------------------------
# step1:将上面生成的List传入get_batch() ,转换类型,产生一个输入队列queue,因为img和lab
# 是分开的,所以使用tf.train.slice_input_producer(),然后用tf.read_file()从队列中读取图像
# image_W, image_H, :设置好固定的图像高度和宽度
# 设置batch_size:每个batch要放多少张图片
# capacity:一个队列最大多少
def get_batch(image, label, batch_size,image_W=24, image_H=24, capacity=500):
# 转换类型
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]) # read img from a queue
# step2:将图像解码,不同类型的图像不能混在一起,要么只用jpeg,要么只用png等。
image = tf.image.decode_jpeg(image_contents, channels=3)
# step3:数据预处理,对图像进行旋转、缩放、裁剪、归一化等操作,让计算出的模型更健壮。
image = tf.image.resize_image_with_crop_or_pad(image, image_W, image_H)
image = tf.image.per_image_standardization(image)
# step4:生成batch
# image_batch: 4D tensor [batch_size, width, height, 3],dtype=tf.float32
# label_batch: 1D tensor [batch_size], dtype=tf.int32
image_batch, label_batch = tf.train.batch([image, label],
batch_size=batch_size,
num_threads=32,
capacity=capacity)
# 重新排列label,行数为[batch_size]
label_batch = tf.reshape(label_batch, [batch_size])
image_batch = tf.cast(image_batch, tf.float32)
return image_batch, label_batch
def create_batch(batch_size,ratio):
tra_images, tra_labels, val_images, val_labels=get_files(train_dir, ratio)
tra_image_batch, tra_label_batch=get_batch(tra_images, tra_labels, batch_size)
val_images_batch, val_labels_batch = get_batch(val_images, val_labels, batch_size)
return tra_image_batch, tra_label_batch, val_images_batch, val_labels_batch