1764|3

400

帖子

9

TA的资源

纯净的硅(初级)

楼主
 

嘉楠K510开发板的AI应用(第二篇) [复制链接]

 

这篇的内容和板卡其实关系不是特别大,只是应该内嵌在

https://bbs.eeworld.com.cn/thread-1226738-1-1.html

中,介绍了如何在电脑中训练一个模型,后续会介绍模型的转换和在开发板里的使用,

文章看起来很枯燥,而且一半是引用了网上的资料,结合个人理解,做了整合。

训练的源代码train_0.py、train_2.py已经测试通过,在下载中心也能获取。

https://download.eeworld.com.cn/detail/tobot/625727

https://download.eeworld.com.cn/detail/tobot/625726

首先说明:我这里使用Keras做API导入,后端使用TensorFlow,相关的python库都可以直接使用pip从网络下载安装。如果跑源码提示缺少什么库,直接pip install就行。

事实上,代码里面用的是tf.keras(好像不是完整的Keras,区别我也说不清楚,但只要能用就行)

首先是寻找合适数据源,如前文所述,目标是和图形相关,那么数据源是大量的图片,图片应该有一定的预处理(比如对目标进行标注)。大数据训练一般需要以T以上的数据才能有足够的精度,但我们只做简单演示,这里只做演示,就不拿那么多图片来训练了。

这里附上两个我写的小程序,一个可以将视频转换成图片(爬电影),一个可以从百度拉图片。图片准备好以后,大致看一下,把明显会造成数据污染的错误图片挑出来删除。

https://download.eeworld.com.cn/detail/tobot/625724

https://download.eeworld.com.cn/detail/tobot/625723

 

图片做一下预处理(如果是物体,可能需要设计旋转等多角度的图,人物的脸部或动作不需要这个),这里也提供一个小程序,把图片整理为方块(当然在导入数据时也可以做这一步,具体是否需要看个人吧)。

https://download.eeworld.com.cn/detail/tobot/625725

然后随机分为两组,一组用于训练,另一组用于对照训练效果,一般大致比例为10:1~2:1吧(这个只是习惯,实际上验证比训练库大也行的)。

目录结构如下:

data

∟train

∟obj1

   ∟train_obj1_pic1

   ∟train_obj1_pic2

   ∟……

∟obj2

   ∟train_obj2_pic1

   ∟train_obj2_pic2

   ∟……

∟test

∟obj1

   ∟test_obj1_pic1

   ∟test_obj1_pic2

   ∟……

∟obj2

   ∟test_obj2_pic1

   ∟test_obj2_pic2

   ∟……

在目录train和test中的各obj目录里面放的图片都是可以已经人工预先分类好的,目录记得保持一致,obj数量可以不限制,但目标类越多,所需训练的数据源就要更多,迭代次数也需要相应增加。

接下来安排训练,一般来说,训练都是按照如下步骤:

1)导入必要的库

2)载入数据

3)搭建神经网络

4)配置训练方法(compile)

5)执行训练过程(fit)

6)统计参数(summary)

其中第6步,做或者不做,都是可以的。

其重点步骤在2、3、4、5。

第二步:载入数据

一般使用tf.keras.preprocessing.image.ImageDataGenerator

tf.keras.preprocessing.image.ImageDataGenerator(

    featurewise_center=False, samplewise_center=False,

    featurewise_std_normalization=False, samplewise_std_normalization=False,

    zca_whitening=False, zca_epsilon=1e-06, rotation_range=0, width_shift_range=0.0,

    height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0,

    channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False,

    vertical_flip=False, rescale=None, preprocessing_function=None,

    data_format=None, validation_split=0.0, dtype=None

)

大多数参数保持缺省即可。大家想看具体的可以自己找手册,我这里不水字数(下同)。

ImageDataGenerator的flow_from_directory就是从文件夹里面找图片,

target_size,默认为(256, 256),图像将被resize成该尺寸,所以尽可能不要用长宽比差距太大的图片。

color_mode:所使用的颜色模式,可选"grayscale"或"rgb",默认为"rgb",代表这些图片是否会被转换为单通道或三通道的图片,对于灰度图片,一般用在车牌识别,文字识别方面。k510开发板中有相关应用。彩色图片则是我们生活中比较常见的,物品分类应用较多。

classes:可选参数,默认为None,可以通过子文件夹名称/结构自动推断,每一个子文件夹都会被认为是一个新的类,类别的顺序将按照字母表顺序映射到标签值。通过属性class_indices可获得文件夹名与类的序号的对应字典。

class_mode:"categorical"、"binary"、"sparse"或None之一。默认为“categorical”。该参数决定了返回的标签数组的形式,"categorical"会返回2D的one-hot编码标签,"binary"返回1D的二值标签,"sparse"返回1D的整数标签,如果为None则不返回任何标签, 生成器将仅仅生成batch数据, 这种情况在使用model.predict_generator()和model.evaluate_generator()等函数时会用到。

batch_size: batch数据的大小,默认32,会产生大量数据,如果电脑不够强悍,最好改小一点。

shuffle: 是否打乱数据,默认为True

seed: 可选参数,打乱数据和进行变换时的随机数种子,最好不改,改了每次跑的结果都相同,想想就没啥用。

save_to_dir: None或字符串,该参数能把生成的图片保存起来,用以可视化或者给其他人使用。后面的几个参数都是为它服务的。

save_prefix:字符串,保存提升后图片时使用的前缀, 仅当设置了save_to_dir时生效

save_format:"png"或"jpeg"之一,指定保存图片的数据格式,默认"jpeg"

 

第三步:

搭建神经网络可以采用序列模型,逐层搭建(例如train_0.py),这里也只介绍一下几个常用的层:

卷积层

tf.keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid',

  data_format=None, dilation_rate=(1, 1), activation=None)

其中filter为卷积核个数,

kernel_size为卷积核尺寸,如果是正方形,则用一个整数表示;如果是长方形,则需要明确指明高用h表示,宽用w表示,可以用元组或者列表的形式表示两者(如:[h,w]或者{h, w})

strides为卷积步长,默认横纵向滑动步长均为1(1,1),也可以设置其他步长(纵向步长,横向步长)

padding 可以是 ”valid“或者"same",使用same则是用全0填充,这样可以保持输入与输出相同。

data_format指明输入数据的格式,缺省为channels_first,即(图片数量,通道数, 长,宽),如果改为channels_last,则输入格式为(图片数量,长,宽,通道数)。

activaton:激活函数,相当于经过卷积输出后,再经过一次激活函数(常见的激活函数有relu,softmax,selu)

在这一层里,使用了input_shape = (128, 128, 3)接收图片向量(大小、颜色),它输出的是中间形态的结果,该结果不能直接用来做最终结果,要得到最终结果,我们需要为上面的卷积网络添加一层输出层,也就是所谓的拉直层,直接把它的结果压扁成为二维的。

拉直层

keras.layers.Flatten(),这一层就是把图片向量拉成平的。

全连接层

tf.keras.layers.Dense(神经元个数,activation = "激活函数“,kernel_regularizer = "正则化方式)

其中:activation可选 relu 、softmax、 sigmoid、 tanh等,这里选择的是relu。

卷积操作产生了太多的数据,如果没有max pooling对这些数据进行压缩,那么网络的运算量将会非常巨大,可以在层和层之间放置MaxPooling2D层,可以把卷积操作得到的结果进一步“挤压”出更有用的信息。

tf.keras.layers.MaxPooling2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

其中最常用的是kernel_size(int or tuple)参数,用于设置max pooling的窗口大小。

 

也可以调用现成的卷积网络(例如train_2.py),可以从

链接已隐藏,如需查看请登录或者注册

下载resnet,下载完成以后放在“.keras/models/”目录下(windows在“C:\Users\用户名\”去找)。

当然如果对网络有自信,执行时也可以让程序自动下载。

 

第四步:

配置训练方法,主要是compile的参数(优化器, 损失函数)选取。执行

model.compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)

简单介绍其参数:

optimizer:预定义优化器名或优化器对象,可以为:

       “sgd” 或者 tf.optimizers.SGD(lr = 学习率, decay = 学习率衰减率,momentum = 动量参数);

       “adagrad” 或者 tf.keras.optimizers.Adagrad(lr = 学习率, decay = 学习率衰减率);

       “adadelta” 或者 tf.keras.optimizers.Adadelta(lr = 学习率,decay = 学习率衰减率);

       “adam” 或者 tf.keras.optimizers.Adam(lr = 学习率, decay = 学习率衰减率)。

loss:预定义损失函数名或一个目标函数。可以使用:

       “mse” 或者 “mean squared error” 或者 tf.keras.losses.MeanSquaredError();

       “sparse_categorical_crossentropy” 或 tf.keras.losses.SparseCatagoricalCrossentropy(from_logits = False)

Metrics:评估模型在训练和测试时的性能的指标。

       “accuracy” :

“sparse_accuracy":

“sparse_categorical_accuracy”

sample_weight_mode:

       “temporal”:按时间步为样本赋权(2D权矩阵)

       “None”(缺省),代表按样本赋权(1D权)。

 

第五步:

使用fit执行训练。

model.fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)

x:输入数据。如果模型只有一个输入,那么x的类型是numpy array,如果模型有多个输入,那么x的类型应当为list,list的元素是对应于各个输入的numpy array。如果模型的每个输入都有名字,则可以传入一个字典,将输入名与其输入数据对应起来。

y:标签,numpy array。如果模型有多个输出,可以传入一个numpy array的list。如果模型的输出拥有名字,则可以传入一个字典,将输出名与其标签对应起来。

batch_size:整数,指定进行梯度下降时每个batch包含的样本数。训练时一个batch的样本会被计算一次梯度下降,使目标函数优化一步。

epochs:整数,训练终止时的epoch值,训练将在达到该epoch值时停止,当没有设置initial_epoch时,它就是训练的总轮数,否则训练的总轮数为epochs - inital_epoch

verbose:日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出一行记录

callbacks:list,其中的元素是keras.callbacks.Callback的对象。这个list中的回调函数将会在训练过程中的适当时机被调用,参考回调函数

validation_data:形式为(X,y)或(X,y,sample_weights)的tuple,是指定的验证集。此参数将覆盖validation_spilt。

shuffle:布尔值,表示是否在训练过程中每个epoch前随机打乱输入样本的顺序。

initial_epoch: 从该参数指定的epoch开始训练,在继续之前的训练时有用。

steps_per_epoch: 一个epoch包含的步数(每一步是一个batch的数据送入),当使用如TensorFlow数据Tensor之类的输入张量进行训练时,默认的None代表自动分割,即数据集样本数/batch样本数。

validation_steps: 仅当steps_per_epoch被指定时有用,在验证集上的step总数。

 

 

对于训练结果,可以在训练完成以后保存,也可以在进行训练的过程中,使用“快照”的方式把训练好的模型以checkpoints形式保存下来,这样可以在训练结果之上再次训练。

最新回复

非常专业的帖子,萌新入门,已经有了开发板,想向大佬学习一下,方便加个联系方式嘛。谢谢分享。   详情 回复 发表于 2023-2-7 10:22
点赞 关注
 
 

回复
举报

6968

帖子

11

TA的资源

版主

沙发
 

非常专业的帖子,哪天如果有板子了,也跟着学习一下。谢谢分享。

 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

非常专业的帖子,萌新入门,已经有了开发板,想向大佬学习一下,方便加个联系方式嘛。谢谢分享。

点评

邮箱xp2xp@126.com,微信“晶晶言言是我的宝”  详情 回复 发表于 2023-2-7 23:44
 
 
 

回复

400

帖子

9

TA的资源

纯净的硅(初级)

4
 
xiaobu_AI 发表于 2023-2-7 10:22 非常专业的帖子,萌新入门,已经有了开发板,想向大佬学习一下,方便加个联系方式嘛。谢 ...

邮箱xp2xp@126.com,微信“晶晶言言是我的宝”

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表