基于卷积神经网络的mnist手写体识别

1、卷积神经网络

1.1、什么是卷积神经网络

首先,卷积神经网络的概念,百度是这么给出解释的——卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一 。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification),因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)。

太长了。简单的理解一下,卷积神经网络(CNN)其实就是一种人工神经网络。它很擅长于处理图像特别是大图像的相关机器学习问题。

1.2、卷积神经网络的原理

我们所熟知的神经网络的构成如图:

其实卷积神经网络依然是层级网络,但是其中的层的功能做了一些变化,即传统神经网络的优化。

一个卷积神经网络由很多层组成,它们的输入是三维的,输出也是三维的,有的层有参数,有的层不需要参数。

其中除了输入层和输出层。卷积神经网络的隐含层通常包括以下几种层:
1、卷积层
2、池化层
3、全连接层
在一些更为现代的算法中可能有Inception模块、残差块(residual block)等复杂构筑。

卷积层:
1、卷积核

积层的功能是对输入数据进行特征提取,其内部包含多个卷积核,组成卷积核的每个元素都对应一个权重系数和一个偏差量(bias vector),类似于一个前馈神经网络的神经元(neuron)。卷积层内每个神经元都与前一层中位置接近的区域的多个神经元相连,区域的大小取决于卷积核的大小。卷积核在工作时,会有规律地扫过输入特征,在感受野内对输入特征做矩阵元素乘法求和并叠加偏差量:
式中的求和部分等价于求解一次交叉相关(cross-correlation)。b为偏差量,
Zl和Zl+1表示第l+1层的卷积。
也被称为特征图(feature map),
Ll+1为Zl+1的尺寸,这里假设特征图长宽相同。
Z(i,j)对应特征图的像素,K为特征图的通道数,
f、s0和p是卷积层参数,对应卷积核大小、卷积步长(stride)和填充层数(padding)层数 。

2、卷积层参数
卷积层参数包括卷积核大小、步长和填充,三者共同决定了卷积层输出特征图的尺寸,是卷积神经网络的超参数。其中卷积核大小可以指定为小于输入图像尺寸的任意值,卷积核越大,可提取的输入特征越复杂。
卷积步长定义了卷积核相邻两次扫过特征图时位置的距离,卷积步长为1时,卷积核会逐个扫过特征图的元素,步长为n时会在下一次扫描跳过n-1个像素。

3、激励函数
卷积层中包含激励函数以协助表达复杂特征,其表示形式如下:

池化层:
在卷积层进行特征提取后,输出的特征图会被传递至池化层进行特征选择和信息过滤。池化层包含预设定的池化函数,其功能是将特征图中单个点的结果替换为其相邻区域的特征图统计量。池化层选取池化区域与卷积核扫描特征图步骤相同,由池化大小、步长和填充控制。

全连接层:
全连接层的作用就是把所有局部特征结合变成全局特征,用来计算最后每一类的得分。
卷积神经网络中的全连接层等价于传统前馈神经网络中的隐含层。全连接层通常搭建在卷积神经网络隐含层的最后部分,并只向其它全连接层传递信号。特征图在全连接层中会失去3维结构,被展开为向量并通过激励函数传递至下一层。
【原理部分参考百度百科】

2、手写体识别

利用卷积神经网络进行mnist手写体识别。
以下是两种训练代码。
注意:下面的两个代码是要用到TensorFlow的,至于是安装GPU版本的还是CPU版本的,看个人喜好。
但是我使用的是CPU版本的,因为安装方便,但是运行速度不如GPU快。

2.1、两份代码

1、trainMnistFromImages.py

#coding:utf8
import os
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_datasess = tf.InteractiveSession()def getTrain():train=[[],[]] # 指定训练集的格式,一维为输入数据,一维为其标签# 读取所有训练图像,作为训练集train_root="Mnist手写体训练\mnist_train" labels = os.listdir(train_root)for label in labels:imgpaths = os.listdir(os.path.join(train_root,label))for imgname in imgpaths:img = cv2.imread(os.path.join(train_root,label,imgname),0)array = np.array(img).flatten() # 将二维图像平铺为一维图像array=MaxMinNormalization(array)train[0].append(array)label_ = [0,0,0,0,0,0,0,0,0,0]label_[int(label)] = 1train[1].append(label_)train = shuff(train)return traindef getTest():test=[[],[]] # 指定训练集的格式,一维为输入数据,一维为其标签# 读取所有训练图像,作为训练集test_root="mnist_test" labels = os.listdir(test_root)for label in labels:imgpaths = os.listdir(os.path.join(test_root,label))for imgname in imgpaths:img = cv2.imread(os.path.join(test_root,label,imgname),0)array = np.array(img).flatten() # 将二维图像平铺为一维图像array=MaxMinNormalization(array)test[0].append(array)label_ = [0,0,0,0,0,0,0,0,0,0]label_[int(label)] = 1test[1].append(label_)test = shuff(test)return test[0],test[1]def shuff(data):temp=[]for i in range(len(data[0])):temp.append([data[0][i],data[1][i]])import randomrandom.shuffle(temp)data=[[],[]]for tt in temp:data[0].append(tt[0])data[1].append(tt[1])return datacount = 0
def getBatchNum(batch_size,maxNum):global countif count ==0:count=count+batch_sizereturn 0,min(batch_size,maxNum)else:temp = countcount=count+batch_sizeif min(count,maxNum)==maxNum:count=0return getBatchNum(batch_size,maxNum)return temp,min(count,maxNum)def MaxMinNormalization(x):x = (x - np.min(x)) / (np.max(x) - np.min(x))return x# 1、权重初始化,偏置初始化
# 为了创建这个模型,我们需要创建大量的权重和偏置项
# 为了不在建立模型的时候反复操作,定义两个函数用于初始化
def weight_variable(shape):initial = tf.truncated_normal(shape,stddev=0.1)#正太分布的标准差设为0.1return tf.Variable(initial)
def bias_variable(shape):initial = tf.constant(0.1,shape=shape)return tf.Variable(initial)# 2、卷积层和池化层也是接下来要重复使用的,因此也为它们定义创建函数
# tf.nn.conv2d是Tensorflow中的二维卷积函数,参数x是输入,w是卷积的参数
# strides代表卷积模块移动的步长,都是1代表会不遗漏地划过图片的每一个点,padding代表边界的处理方式
# padding = 'SAME',表示padding后卷积的图与原图尺寸一致,激活函数relu()
# tf.nn.max_pool是Tensorflow中的最大池化函数,这里使用2 * 2 的最大池化,即将2 * 2 的像素降为1 * 1的像素
# 最大池化会保留原像素块中灰度值最高的那一个像素,即保留最显著的特征,因为希望整体缩小图片尺寸
# ksize:池化窗口的大小,取一个四维向量,一般是[1,height,width,1]
# 因为我们不想再batch和channel上做池化,一般也是[1,stride,stride,1]
def conv2d(x, w):return tf.nn.conv2d(x, w, strides=[1,1,1,1],padding='SAME') # 保证输出和输入是同样大小
def max_pool_2x2(x):return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1],padding='SAME')iterNum = 1000
batch_size=1024print("load train dataset.")
train=getTrain()
print("load test dataset.")
test0,test1=getTest()# 3、参数
# 这里的x,y_并不是特定的值,它们只是一个占位符,可以在TensorFlow运行某一计算时根据该占位符输入具体的值
# 输入图片x是一个2维的浮点数张量,这里分配给它的shape为[None, 784],784是一张展平的MNIST图片的维度
# None 表示其值的大小不定,在这里作为第1个维度值,用以指代batch的大小,means x 的数量不定
# 输出类别y_也是一个2维张量,其中每一行为一个10维的one_hot向量,用于代表某一MNIST图片的类别
x = tf.placeholder(tf.float32, [None,784], name="x-input")
y_ = tf.placeholder(tf.float32,[None,10]) # 10列# 4、第一层卷积,它由一个卷积接一个max pooling完成
# 张量形状[5,5,1,32]代表卷积核尺寸为5 * 5,1个颜色通道,32个通道数目
w_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32]) # 每个输出通道都有一个对应的偏置量
# 我们把x变成一个4d 向量其第2、第3维对应图片的宽、高,最后一维代表图片的颜色通道数(灰度图的通道数为1,如果是RGB彩色图,则为3)
x_image = tf.reshape(x,[-1,28,28,1])
# 因为只有一个颜色通道,故最终尺寸为[-1,28,28,1],前面的-1代表样本数量不固定,最后的1代表颜色通道数量
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1) # 使用conv2d函数进行卷积操作,非线性处理
h_pool1 = max_pool_2x2(h_conv1)                          # 对卷积的输出结果进行池化操作# 5、第二个和第一个一样,是为了构建一个更深的网络,把几个类似的堆叠起来
# 第二层中,每个5 * 5 的卷积核会得到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)# 输入的是第一层池化的结果
h_pool2 = max_pool_2x2(h_conv2)# 6、密集连接层
# 图片尺寸减小到7 * 7,加入一个有1024个神经元的全连接层,
# 把池化层输出的张量reshape(此函数可以重新调整矩阵的行、列、维数)成一些向量,加上偏置,然后对其使用Relu激活函数
w_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1,7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)# 7、使用dropout,防止过度拟合
# dropout是在神经网络里面使用的方法,以此来防止过拟合
# 用一个placeholder来代表一个神经元的输出
# tf.nn.dropout操作除了可以屏蔽神经元的输出外,
# 还会自动处理神经元输出值的scale,所以用dropout的时候可以不用考虑scale
keep_prob = tf.placeholder(tf.float32, name="keep_prob")# placeholder是占位符
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)# 8、输出层,最后添加一个softmax层
w_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2, name="y-pred")# 9、训练和评估模型
# 损失函数是目标类别和预测类别之间的交叉熵
# 参数keep_prob控制dropout比例,然后每100次迭代输出一次日志
cross_entropy = tf.reduce_sum(-tf.reduce_sum(y_ * tf.log(y_conv),reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# 预测结果与真实值的一致性,这里产生的是一个bool型的向量
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
# 将bool型转换成float型,然后求平均值,即正确的比例
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 初始化所有变量,在2017年3月2号以后,用 tf.global_variables_initializer()替代tf.initialize_all_variables()
sess.run(tf.initialize_all_variables())# 保存最后一个模型
saver = tf.train.Saver(max_to_keep=1)for i in range(iterNum):for j in range(int(len(train[1])/batch_size)):imagesNum=getBatchNum(batch_size,len(train[1]))batch = [train[0][imagesNum[0]:imagesNum[1]],train[1][imagesNum[0]:imagesNum[1]]]train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})if i % 2 == 0:train_accuracy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1],keep_prob: 1.0})print("Step %d ,training accuracy %g" % (i, train_accuracy))
print("test accuracy %f " % accuracy.eval(feed_dict={x: test0, y_:test1, keep_prob: 1.0}))
# 保存模型于文件夹
saver.save(sess,"save/model")

这一份代码,是将所有的二维图像,平铺成一维数据,并且在代码中规定的卷积模块的步长是1,即每张图片的每一块,都要全部划到。

2、trainMnistFromPackage.py

import tensorflow as tf
import numpy as np # 习惯加上这句,但这边没有用到
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)sess = tf.InteractiveSession()# 1、权重初始化,偏置初始化
# 为了创建这个模型,我们需要创建大量的权重和偏置项
# 为了不在建立模型的时候反复操作,定义两个函数用于初始化
def weight_variable(shape):initial = tf.truncated_normal(shape,stddev=0.1)#正太分布的标准差设为0.1return tf.Variable(initial)
def bias_variable(shape):initial = tf.constant(0.1,shape=shape)return tf.Variable(initial)# 2、卷积层和池化层也是接下来要重复使用的,因此也为它们定义创建函数
# tf.nn.conv2d是Tensorflow中的二维卷积函数,参数x是输入,w是卷积的参数
# strides代表卷积模块移动的步长,都是1代表会不遗漏地划过图片的每一个点,padding代表边界的处理方式
# padding = 'SAME',表示padding后卷积的图与原图尺寸一致,激活函数relu()
# tf.nn.max_pool是Tensorflow中的最大池化函数,这里使用2 * 2 的最大池化,即将2 * 2 的像素降为1 * 1的像素
# 最大池化会保留原像素块中灰度值最高的那一个像素,即保留最显著的特征,因为希望整体缩小图片尺寸
# ksize:池化窗口的大小,取一个四维向量,一般是[1,height,width,1]
# 因为我们不想再batch和channel上做池化,一般也是[1,stride,stride,1]
def conv2d(x, w):return tf.nn.conv2d(x, w, strides=[1,1,1,1],padding='SAME') # 保证输出和输入是同样大小
def max_pool_2x2(x):return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1],padding='SAME')# 3、参数
# 这里的x,y_并不是特定的值,它们只是一个占位符,可以在TensorFlow运行某一计算时根据该占位符输入具体的值
# 输入图片x是一个2维的浮点数张量,这里分配给它的shape为[None, 784],784是一张展平的MNIST图片的维度
# None 表示其值的大小不定,在这里作为第1个维度值,用以指代batch的大小,means x 的数量不定
# 输出类别y_也是一个2维张量,其中每一行为一个10维的one_hot向量,用于代表某一MNIST图片的类别
x = tf.placeholder(tf.float32, [None,784], name="x-input")
y_ = tf.placeholder(tf.float32,[None,10]) # 10列# 4、第一层卷积,它由一个卷积接一个max pooling完成
# 张量形状[5,5,1,32]代表卷积核尺寸为5 * 5,1个颜色通道,32个通道数目
w_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32]) # 每个输出通道都有一个对应的偏置量
# 我们把x变成一个4d 向量其第2、第3维对应图片的宽、高,最后一维代表图片的颜色通道数(灰度图的通道数为1,如果是RGB彩色图,则为3)
x_image = tf.reshape(x,[-1,28,28,1])
# 因为只有一个颜色通道,故最终尺寸为[-1,28,28,1],前面的-1代表样本数量不固定,最后的1代表颜色通道数量
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1) # 使用conv2d函数进行卷积操作,非线性处理
h_pool1 = max_pool_2x2(h_conv1)                          # 对卷积的输出结果进行池化操作# 5、第二个和第一个一样,是为了构建一个更深的网络,把几个类似的堆叠起来
# 第二层中,每个5 * 5 的卷积核会得到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)# 输入的是第一层池化的结果
h_pool2 = max_pool_2x2(h_conv2)# 6、密集连接层
# 图片尺寸减小到7 * 7,加入一个有1024个神经元的全连接层,
# 把池化层输出的张量reshape(此函数可以重新调整矩阵的行、列、维数)成一些向量,加上偏置,然后对其使用Relu激活函数
w_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1,7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)# 7、使用dropout,防止过度拟合
# dropout是在神经网络里面使用的方法,以此来防止过拟合
# 用一个placeholder来代表一个神经元的输出
# tf.nn.dropout操作除了可以屏蔽神经元的输出外,
# 还会自动处理神经元输出值的scale,所以用dropout的时候可以不用考虑scale
keep_prob = tf.placeholder(tf.float32, name="keep_prob")# placeholder是占位符
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)# 8、输出层,最后添加一个softmax层
w_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2, name="y-pred")# 9、训练和评估模型
# 损失函数是目标类别和预测类别之间的交叉熵
# 参数keep_prob控制dropout比例,然后每100次迭代输出一次日志
cross_entropy = tf.reduce_sum(-tf.reduce_sum(y_ * tf.log(y_conv),reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# 预测结果与真实值的一致性,这里产生的是一个bool型的向量
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
# 将bool型转换成float型,然后求平均值,即正确的比例
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 初始化所有变量,在2017年3月2号以后,用 tf.global_variables_initializer()替代tf.initialize_all_variables()
sess.run(tf.initialize_all_variables())# 保存最后一个模型
saver = tf.train.Saver(max_to_keep=1)for i in range(1000):batch = mnist.train.next_batch(64)if i % 100 == 0:train_accuracy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1],keep_prob: 1.0})print("Step %d ,training accuracy %g" % (i, train_accuracy))train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
print("test accuracy %f " % accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))# 保存模型于文件夹
saver.save(sess,"save/model")

在这里,这两个代码都可以对卷积神经网络进行训练。但是建议选择第二份。
因为,第一个代码trainMnistFromImages.py,是将每张图像进行卷积,所以速度会非常非常的慢,而且非常占用内存,我的16G内存运行都占用了百分之九十几。
而第二份,是正在卷积神经网络的基础上,对图片进行批量处理。
虽然两份代码的卷积模块的步长都是1,即图像数据的每一处都会划到。但是进行批处理后,既能尽可能的保证正确率,又可以不占用那么多资源和时间。

2.2、遇到的错误

另外,大家在运行代码的时候,可能会遇到一些错误,所以我在这里把我遇到的一些错误分享一下。
遇到的错误以及解决方法:
1、cv2出现错误:

这里注意,cv2是opencv库中的,在这里的cv2出现问题,是因为在cv2模块下还有一个cv2模块,所以系统找不到需要用的cv2,简单的让vscode不报错的方法是在添加包的时候
将import cv2
改为
from cv2 import cv2 as cv

2、你的CPU版的TensorFlow的问题:
有时候,你CPU是没问题的,但是TensorFlow无法工作。
原因是下载TensorFlow的版本不支持cpu的AVX2编译。
可能是因为安装时使用的pip install tensorflow ,这样默认会下载X86_64的SIMD版本。
我很久才发现自己有这个错误,根据网上百度的解答,有两种方法。
解决一:
import os
os.environ[“TF_CPP_MIN_LOG_LEVEL”]=‘1’ # 这是默认的显示等级,显示所有信息
os.environ[“TF_CPP_MIN_LOG_LEVEL”]=‘2’ # 只显示 warning 和 Error
os.environ[“TF_CPP_MIN_LOG_LEVEL”]=‘3’ # 只显示 Error

解决二:彻底解决,换成支持cpu用AVX2编译的TensorFlow版本。
进入这个网址:windows下载地址
我的版本是CPU,有的同学安装的GPU,所以根据自己的需求下载。

2.3、程序测试

我自己做了五个图

但是遇到了以下错误
即图片无法reshape,分析原因是图像的问题。所以我在百度上找mnist数据集照片测试。
下列分别是几个测试结果:
1、对4的测试

2、对7的测试

3、对8的测试

4、对5的测试
在这几对图片中,我们可以看出来,有几张图片确实对于本身代表的数字来说,实在是变形的有点厉害,我们平常单独见到也不会联想到该数字,但是程序却识别出来了。而有些图片却不会显得很夸张,然而程序却识别不出来。

2.4结果分析

有些图片很夸张,以至于连肉眼都观察不出来,但是却能识别出来其本身所代表的数字,可能是因为这一类相似的图片数量较多,所以训练出来的神经网络是可以识别出来的,但是有些图片并不是很夸张,肉眼一辩就可以知道是什么数字,然而程序却识别错误,可能是该类的图片数量较少,也有可能是具有其他数字意义的图片与此图片类似,所以得到训练出来的神经网络识别错误。

基于卷积神经网络的mnist手写体识别相关推荐

  1. python神经网络案例——CNN卷积神经网络实现mnist手写体识别

    分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开 全栈工程师开发手册 (作者:栾鹏) python教程全解 CNN卷积神经网络的理论教程参考 ...

  2. 基于卷积神经网络的小麦病害识别方法

    基于卷积神经网络的小麦病害识别方法 1.研究思路 首先以小麦病害图片资料为基础,利用中值滤波法.直方图阈值法等对图像进行去背景.去噪.病斑分割等预处理形成样本库,然后利用卷积神经网络构建一个具有五层结 ...

  3. 2022-05-08 基于卷积神经网络ResNet的车型识别(实验)

    人工智能应用--基于卷积神经网络ResNet的车型识别 一.实验目的 熟悉ResNet卷积神经网络 熟悉物体检测+识别的整体流程 二.实验内容与记录 在给定的6类车型图片数据库上,使用ResNet18 ...

  4. 基于卷积神经网络的人脸表情识别应用--AR川剧变脸(二)

    本项目将在Android上实现一种通过识别表情类别,从而给人脸戴上不同样式脸谱的AR软件,效果如下: 基于表情识别的脸谱换脸AR安卓APP效果演示 想要实现这样一个软件,核心就是两部分: 1)使用卷积 ...

  5. 基于卷积神经网络的人脸表情识别应用--AR川剧变脸(一)

    1.摘要 本项目将在Android上实现一种通过识别表情类别,从而给人脸戴上不同样式脸谱的AR软件,效果如下: 基于表情识别的脸谱换脸AR安卓APP效果演示 通过深度学习和Keras训练一个人脸表情识 ...

  6. 基于卷积神经网络的不良地质体识别与分类

    在泛函分析中,卷积.旋积或摺积(英语:Convolution)是通过两个函数f 和g 生成第三个函数的一种数学算子,表征函数f 与g经过翻转和平移的重叠部分的面积. 如果将参加卷积的一个函数看作区间的 ...

  7. 1.卷积神经网络入门-训练手写体识别

    文章目录 前言 一.代码和运行结果 二.图例解读代码过程 总结 前言 笔者权当做笔记,借鉴的是<Python 深度学习>这本书,里面的代码也都是书上的代码,用的是jupyter noteb ...

  8. 基于卷积神经网络的大豆病害识别

    1.研究内容 植物已经成为一种重要的能源,是解决全球变暖问题的基础.然而,植物病害正威胁着这一重要来源的生计.卷积神经网络(CNN)在物体识别和图像分类问题上表现出了卓越的性能(超过了人类).本文介绍 ...

  9. 【Pytorch】基于卷积神经网络实现的面部表情识别

    作者:何翔 学院:计算机学院 学号:04191315 班级:软件1903 转载请标注本文链接: https://blog.csdn.net/HXBest/article/details/1219812 ...

  10. 【毕业设计】基于卷积神经网络的植物花卉识别系统

    系统演示视频: [毕业设计]基于卷积神经网络的植物花卉分类系统 本项目使用到的技术包括:卷积神经网络(CNN)算法,Django框架搭建网站,CNN模型调优. 项目包括四部分: 1.数据集 2.模型训 ...

最新文章

  1. 文档信息的向量化-NNLM模型和word2vec
  2. 一个MySQL锁和面试官大战三十回合,我霸中霸!
  3. Oracle之AUTHID CURRENT_USER
  4. Oralce/MySQL 默认隔离级别对比
  5. Nodejs的各种数据库驱动地址汇总
  6. 【信号与系统】三大变换公式表 | 傅里叶变换 | 拉普拉斯变换 | Z变换
  7. 斐讯K2刷回原厂固件
  8. 树莓派自启动配置端口映射及启动jar
  9. mariadb10 java包_编译安装MariaDB-10.0.21
  10. C# winform 如何让TextBox文本内容垂直居中?
  11. 零基础理财入门书籍分享
  12. DNA 5. 基因组变异文件VCF格式详解
  13. scratch实现弹跳小球2
  14. Acme CAD Converter 命令行模式
  15. STM32 IO口模拟ISO7816(PSAM卡)协议
  16. maven 多模块项目如何导入其他模块的第三方 jar 包
  17. Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl
  18. win10 分屏方法
  19. centos7中英文切换
  20. oracle开放查询表权限_Oracle创建用户并给用户授权查询指定表或视图的权限

热门文章

  1. makefile的简单编写
  2. 机器人学相关书籍(长期更新)
  3. 交换机cad图例_各种弱电系统的CAD图纸,包含图例、大样图、系统图及原理图等...
  4. 解决Firefox火狐打不开Axure原型图
  5. 一文读懂FFT,海宁窗(hann)和汉明窗(hamming)的区别,如何选择窗函数
  6. php如何让图片大小自适应,dedecms怎么让图片自适应屏幕大小
  7. 真好玩python教孩子学编程_Python真好玩:教孩子学编程(全彩印刷))简介,目录书摘...
  8. navicat12简体中文专业版免费使用教程
  9. 旅馆业等领域旅客入住身份核验解决方案
  10. 2021全网最全Activiti7教程01(Activiti7详细介绍-欢迎收藏)