9.训练自己的数据集(2):卷积神经网络之花卉分类

本文接上一篇:8.训练自己的数据集(1):TFRecords编写与读取,文件是共享的,不再赘述。

1.先看看训练集与测试集大小:
import tensorflow as tf
import os
import numpy as np
from PIL import Image

#查看tfrecords中数据集的大小
def total_sample(tfrecord_name):
    sample_nums = 0
    for record in tf.python_io.tf_record_iterator(tfrecord_name):
        sample_nums += 1
    return  sample_nums
train_total = total_sample('train.tfrecords')
test_total = total_sample('test.tfrecords')
print(train_total)
print(test_total)

在这里插入图片描述
注意,数据集大小在后面是有用的,test_total与train_total都有用。

2.定义相关参数
#定义相关参数
#图片的尺寸
WITH = 40
HEIGHT = 40
#图片总共由3类,用于one_hot标签
classes_num = 3
#每批次训练图片数量
batch_size = 300
#将所有图片训练一轮所需要的总的训练次数
total_batch = int(train_total/batch_size) 
#总共循环训练轮数
train_epochs = 50
#定义初始学习率
learning_rate = 0.005
3.构建模型并训练测试
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"

#读取tfrecords中数据方法
def read_tfrecords(tfrecord_name,batch_size):
    #将tfrecords读入流中,乱序操作并循环读取
    filename_queue = tf.train.string_input_producer([tfrecord_name]) 
    reader = tf.TFRecordReader()
    #返回文件名和文件
    _, serialized_example = reader.read(filename_queue)
    #取出文件中包含image和label的feature对象
    features = tf.parse_single_example(serialized_example,
                                       features={
                                           'label': tf.FixedLenFeature([], tf.int64),
                                           'img_raw' : tf.FixedLenFeature([], tf.string),
                                       })
    #将字符串解析成图像对应的像素数组
    image = tf.decode_raw(features['img_raw'], tf.uint8)
    #改变像素数组的大小,彩图是3通道的
    image = tf.reshape(image, [WITH, HEIGHT, 3])
    #将像素数组归一化
    image = tf.cast(image,tf.float32)*(1./255)-0.5
    #读取标签
    label = tf.cast(features['label'], tf.int32)
    #将标签制成one_hot
    label = tf.one_hot(label,depth=classes_num,on_value=1)
    #按批次大小乱序读取数据
    x_batch, y_batch = tf.train.shuffle_batch([image,label], 
                                              batch_size=batch_size, 
                                              num_threads=1, capacity=30*batch_size,
                                              min_after_dequeue=15*batch_size)
    return x_batch,y_batch

#获取训练集数据
xs_train,ys_train = read_tfrecords('train.tfrecords',batch_size)
#获取测试集数据
xs_test,ys_test = read_tfrecords('test.tfrecords',test_total)

#定义图片和标签的占位符
#None 表示张量的第一维度可以接受任意长度,3表示图片通道数
x = tf.placeholder(tf.float32,shape = [None,WITH,HEIGHT,3])
#None 表示张量的第一维度可以接受任意长度,class_num表示标签类别个数
y = tf.placeholder(tf.float32,shape = [None,classes_num])
keep_prob  = tf.placeholder(tf.float32)

#定义权重及偏置值变量
W1 = tf.Variable(tf.random_normal(([int(WITH/4)*int(HEIGHT/4)*256,1024])))
b1 = tf.Variable(tf.constant(0.1,shape=[1024]))
W2 = tf.Variable(tf.random_normal(([1024,classes_num])))
b2 = tf.Variable(tf.constant(0.1,shape=[classes_num]))

#定义隐藏层
def hidden_layer(inputs):
    #要用激活函数
    return tf.nn.relu(tf.matmul(inputs,W1)+b1)

#定义权重方法:
def get_filter(shape):
    return tf.Variable(tf.truncated_normal(shape,stddev=0.1))

#定义偏置值方法:
def get_bias(shape):
    return tf.Variable(tf.constant(0.1,shape=shape))

w_con1 = get_filter([5,5,3,128])
b_con1 = get_bias([128])
w_con2 = get_filter([5,5,128,256])
b_con2 = get_bias([256])

#第一层卷积输出,输出大小为 batch_size * WITH * HEIGHT * 15:
h_conv1 = tf.nn.conv2d(x,filter=w_con1,strides=[1,1,1,1],padding='SAME')+b_con1
#激活函数:
h1 = tf.nn.relu(h_conv1)
#第一层池化输出,输出大小为 batch_size * (WITH/2) *(HEIGHT/2) * 15:
h_pool1 = tf.nn.max_pool(h1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#第二层卷积输出,输出大小为 batch_size * (WITH/2) *(HEIGHT/2) * 30:
h_conv2 = tf.nn.conv2d(h_pool1,filter=w_con2,strides=[1,1,1,1],padding='SAME')+b_con2
#激活函数:
h2 = tf.nn.relu(h_conv2)
#第一层池化输出,输出大小为 batch_size * (WITH/4) *(HEIGHT/4) * 30:
h_pool2 = tf.nn.max_pool(h2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

      
#将池化后的输出改变下尺寸,
h_reshape = tf.reshape(h_pool2,[-1,int(WITH/4)*int(HEIGHT/4)*256])
    
#隐藏层输出,并使用dropout
h3 = hidden_layer(h_reshape)

h_drop1 = tf.nn.dropout(h3,keep_prob)

#预测值,这里不用激活函数,因为等下要用tensorflow定义好的softmax交叉熵函数
pred = tf.matmul(h_drop1,W2) + b2

#定义交叉熵
cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=pred,labels=y)

#定义总的损失函数
loss = tf.reduce_mean(cross_entropy)

#定义优化器
opt = tf.train.AdamOptimizer(learning_rate).minimize(loss)

 
#以下是测试模型
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
#准确率:
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

with tf.Session() as sess: 
    #必写内容
    sess.run(tf.global_variables_initializer())
    coord=tf.train.Coordinator()
    threads= tf.train.start_queue_runners(coord=coord)
    
    #开始训练
    print("以下是训练模型每轮训练误差:")
    for epoch in range(train_epochs):
        #定义平均loss值
        avg_loss = 0.
        #循环所有数据
        for i in range(total_batch):
            #获取批次训练数据
            batch_xs,batch_ys = sess.run([xs_train,ys_train])
            _,c,acc = sess.run([opt,loss,accuracy],feed_dict={x:batch_xs,y:batch_ys,keep_prob:0.8})
            #平均loss
            avg_loss += c / total_batch
        #显示每轮的结果
        print('Epoch:',epoch+1,',     loss:','{:.9f}'.format(avg_loss),',     accuracy:','{:.5f}'.format(acc))
        
    print("\n训练模型结束,以下是测试模型准确率:")
    
    #获取测试数据
    test_xs,test_ys = sess.run([xs_test,ys_test])
    acc = sess.run(accuracy,feed_dict={x:test_xs,y:test_ys,keep_prob:1.0})
    print('Accuracy:',acc)
    
    #必写内容
    coord.request_stop()
    coord.join(threads)

在这里插入图片描述
总共训练了50轮,测试正确率57%,很多参数需要调整(比如增加训练次数,添加卷积池化层,改变图片尺寸大小等)。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值