创新实训日记三:cnn模型改进

本周主要工作主要包括以下两个方面:

  • 论文阅读,寻找新实现方法
  • 现有模型的调整和改进

在新读的Eye Tracking for Everyone这篇论文中,作者通过cnns的训练实现了在手机和平板上的视线追踪功能,而且误差在1cm左右,精度较高。

而且对比于之前看的论文(Appearance-Based Gaze Estimation in the Wild)中需要坐标系变换和摄像头位置等参数进行图像的预处理等步骤,新阅读论文中在训练之前需要的图像预处理参数更少,而且由于我们也缺少摄像头等对应的参数,不容易实现原来的方法,我们决定采用新的模型结构在原数据集上进行一下测试
新的模型结构如下图所示
在这里插入图片描述
因为原数据集,缺少脸部完整的图像信息,因此在实际使用该模型的时候,我们只使用了左右眼部经过标准化后的图像,利用两个眼部图像分别进行卷积操作,最后喂入全连接层。
测试代码如下(相比于上一篇的cnn结构,添加了另外一只眼睛的图像做卷积操作,同时修改了loss函数为绝对值)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""

@author: vali
"""

# coding:utf8
 
import tensorflow as tf
import numpy as np
import readMat as rm
import os 
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
 
 
def weight_variable(shape):
	'''
	使用卷积神经网络会有很多权重和偏置需要创建,我们可以定义初始化函数便于重复使用
	这里我们给权重制造一些随机噪声避免完全对称,使用截断的正态分布噪声,标准差为0.1
	:param shape: 需要创建的权重Shape
	:return: 权重Tensor
	'''
	initial = tf.random_normal(shape,stddev=0.01)
	return tf.Variable(initial)
 
 
def bias_variable(shape):
	'''
	偏置生成函数,因为激活函数使用的是ReLU,我们给偏置增加一些小的正值(0.1)避免死亡节点(dead neurons)
	:param shape:
	:return:
	'''
	initial = tf.constant(0.1, shape=shape)
	return tf.Variable(initial)
 
 
def conv2d(x, W):
	'''
	卷积层接下来要重复使用,tf.nn.conv2d是Tensorflow中的二维卷积函数,
	:param x: 输入 例如[5, 5, 1, 32]代表 卷积核尺寸为5x5,1个通道,32个不同卷积核
	:param W: 卷积的参数
		strides:代表卷积模板移动的步长,都是1代表不遗漏的划过图片的每一个点.
		padding:代表边界处理方式,SAME代表输入输出同尺寸
	:return:
	'''
	return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")
 
 
def max_pool_2x2(x):
	'''
	tf.nn.max_pool是TensorFLow中最大池化函数.我们使用2x2最大池化
	因为希望整体上缩小图片尺寸,因而池化层的strides设为横竖两个方向为2步长
	:param x:
	:return:
	'''
	return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
 
 
def train(data,label,test_data,test_label,data1,label1,test_data1,test_label1):
    
	# 使用占位符
    x0 = tf.placeholder(tf.float32, [None, 36,60],'x0')# x为特征  right
    x1 = tf.placeholder(tf.float32, [None, 36,60],'x1')# x1为特征  left
    
    
    y0 = tf.placeholder(tf.float32, [None,2],'y0')
    y1 = tf.placeholder(tf.float32, [None,2],'y1')
    
    y_ = (y0+y1)/2# y_为label,取平均值
    

    
 
	# 卷积中将1x2160转换为36x60x1  [-1,,,]代表样本数量不变 [,,,1]代表通道数
    x_image0 = tf.reshape(x0, [-1, 36, 60, 1])
    
    x_image1 = tf.reshape(x1, [-1, 36, 60, 1])
 
	# 第一个卷积层  [5, 5, 1, 32]代表 卷积核尺寸为5x5,1个通道,32个不同卷积核
	# 创建滤波器权值-->加偏置-->卷积-->池化
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x_image0, W_conv1)+b_conv1) #36x60x1 与32个5x5x1滤波器 --> 36x60x32
    h_pool1 = max_pool_2x2(h_conv1)  # 36x60x32 -->18x30x32
    
    h_conv1_1 = tf.nn.relu(conv2d(x_image1, W_conv1)+b_conv1) #36x60x1 与32个5x5x1滤波器 --> 36x60x32
    h_pool1_1 = max_pool_2x2(h_conv1_1)  # 36x60x32 -->18x30x32
    
 
	# 第二层卷积层 卷积核依旧是5x5 通道为32   有64个不同的卷积核
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) #18x30x32 与64个5x5x32滤波器 --> 18x30x64
    h_pool2 = max_pool_2x2(h_conv2)  #18x30x64 --> 9x15x64
    
    h_conv2_1 = tf.nn.relu(conv2d(h_pool1_1, W_conv2) + b_conv2) #18x30x32 与64个5x5x32滤波器 --> 18x30x64
    h_pool2_1 = max_pool_2x2(h_conv2_1)  #18x30x64 --> 9x15x64
 
    
    #tensor合并
    h_pool2_merge = tf.concat([h_pool2,h_pool2_1],0)  #18x15x64
    
	# h_pool2_merge的大小为18x15x64 转为1-D 然后做FC层
    W_fc1 = weight_variable([18*15*64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2_merge, [-1, 18*15*64])    #18x15x64 --> 17280
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)  #FC层传播 17280--> 1024
 
	# 使用Dropout层减轻过拟合,通过一个placeholder传入keep_prob比率控制
	# 在训练中,我们随机丢弃一部分节点的数据来减轻过拟合,预测时则保留全部数据追求最佳性能
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
 
	# 将Dropout层的输出连接到一个Softmax层,得到最后的概率输出
    W_fc2 = weight_variable([1024, 2])  #2种输出可能
    b_fc2 = bias_variable([2])
    y_conv = (tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
 
	# 定义损失函数,使用均方误差  同时定义优化器  learning rate = 1e-4
    cross_entropy = tf.reduce_mean(tf.abs((y_conv-y_)))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
 
	# 定义评测准确率
    #accuracy = (1-tf.abs(tf.abs(y_conv[0][0]-y_[0])/y_[0]))*(1-tf.abs(tf.abs(y_conv[0][1]-y_[1])/y_[1]))
    accuracy = y_conv
	#开始训练
    #writer = tf.summary.FileWriter("./", tf.get_default_graph())
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer() #初始化所有变量
        sess.run(init_op)
 
        STEPS = 100
        for i in range(STEPS):
			#batch = 5
            batch_x = [data[i*5]]
            batch_y = [label[i*5]]
            
            batch_x1 = [data1[i*5]]
            batch_y1 = [label1[i*5]]
            
            for j in range(1,5):
                batch_x = np.vstack((batch_x,[data[5*i+j]]))
                batch_y =  np.vstack((batch_y,[label[5*i+j]]))
                
                batch_x1 = np.vstack((batch_x1,[data1[5*i+j]]))
                batch_y1 =  np.vstack((batch_y1,[label1[5*i+j]]))
            if i % 2 == 0:
                #train_accuracy = sess.run(accuracy, feed_dict={x:batch_x , y_:batch_y, keep_prob: 1.0})
                train_cross_entropy= sess.run(cross_entropy,feed_dict={x0:batch_x , y0:batch_y,
                                                                       x1:batch_x , y1:batch_y, keep_prob: 1.0})
                print(i,train_cross_entropy)
                    
                
            sess.run(train_step, feed_dict={x0: batch_x, y0: batch_y,
                                            x1: batch_x, y1: batch_y, keep_prob: 0.5})
            
       #test     
        for i in range(10):
			#batch = 5
            batch_x = [test_data[5*i]]
            batch_y = [test_label[5*i]]
            
            
            batch_x1 = [test_data1[5*i]]
            batch_y1 = [test_label1[5*i]]
            
            
            for j in range(1,5):
                batch_x = np.vstack((batch_x,[test_data[5*i+j]]))
                batch_y =  np.vstack((batch_y,[test_label[5*i+j]]))
                
                batch_x1 = np.vstack((batch_x1,[test_data1[5*i+j]]))
                batch_y1 =  np.vstack((batch_y1,[test_label1[5*i+j]]))
           
                #train_accuracy = sess.run(accuracy, feed_dict={x:batch_x , y_:batch_y, keep_prob: 1.0})
            res= sess.run(y_conv,feed_dict={x0:batch_x , y0:batch_y,
                                            x1:batch_x , y1:batch_y, keep_prob: 1.0})
            loss = res - batch_y
            count = 0
            len = 0
            for k in loss:
                if(abs(k[0])<0.1 and abs(k[1])<0.1):
                    count+=1
                len+=1
            print(i,count/len)


 
if __name__=="__main__":
    label,data = rm.getdata('day01.mat')
    label1,data1 = rm.getdata('day01.mat',x=1)
    test_label,test_data=rm.getdata('day02.mat')
    test_label1,test_data1 = rm.getdata('day02.mat',x = 1)
    train(data,label,test_data,test_label,data1,label1,test_data1,test_label1)

测试结果如下图所示

在这里插入图片描述
在同样100轮的训练下,accuracy可以看出有较明显的提升,接下来考虑进行更多轮数的训练并且尝试加入更多的特征。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CNN是卷积神经网络的缩写,是一种深度学习算法。MATLAB是一种高级的计算机语言和环境,常用于科学计算和数据分析。使用MATLAB可以很方便地实现CNN算法。 在MATLAB中实现CNN,需要进行以下步骤: 1. 数据准备:首先,需要准备用于训练和测试的数据集。数据集可以从图像库中获取,也可以通过收集和标记图像来构建自己的数据集。 2. 网络架构设计:决定神经网络的结构,包括输入层、卷积层、池化层、全连接层和输出层等。这些层的参数可以根据具体问题进行调整,例如卷积核的大小、池化窗口的大小等。 3. 模型训练:使用数据集对CNN模型进行训练。通过调整网络参数,使得模型能够适应训练数据并提高精度。训练过程通常包括前向传播、反向传播和参数更新等步骤。 4. 模型评估:使用独立的测试数据对训练得到的模型进行评估。评估指标可以是分类准确率、召回率、精确率等。根据评估结果,可以对模型进行进一步的调整和改进。 在MATLAB中实现CNN,可以使用深度学习工具箱中的相关函数和工具。例如,可以使用convolution2dLayer函数和maxPooling2dLayer函数创建卷积层和池化层,并使用fullyConnectedLayer函数创建全连接层。还可以使用trainNetwork函数进行模型的训练和评估。 总之,在MATLAB中实现CNN,需要进行数据准备、网络架构设计、模型训练和模型评估等步骤。通过使用深度学习工具箱中的函数和工具,可以方便地实现CNN算法,并应用于图像分类、目标检测等问题中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值