感谢关注天善智能,走好数据之路↑↑↑
欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!
对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。
作者:射命丸咲 Python 与 机器学习 爱好者
知乎专栏:https://zhuanlan.zhihu.com/carefree0910-pyml
最终成品的 GitHub 地址:https://github.com/carefree0910/MachineLearning/tree/master/NN
由于神经网络听上去最厉害(?),所以打算先讲一讲这部分
封面图算是最终结果中 CNN 的一个比较简易的呈现;可能有些童鞋还不知道是什么意思,可能有些大神已经看出了一些端倪。总之,我个人的习惯是先说明最终能干什么、然后再来说怎么实现,这样也能避免一些不必要的信息筛选。所以,这一部分主要用于让已经知道一定的基础知识的童鞋知道最后能走多远。
图文并茂是个不错的选择(废话
<1>普通的神经网络,支持各种常见的激活函数如 Sigmoid、Tanh、ReLU 等。以下代码定义了一个含单层隐藏层的、含有 400 个神经元的、以 ReLU 为激活函数、以 Cross Entropy 为损失的神经网络:
nn.add("ReLU",(x.shape[1],400))nn.add("CrossEntropy",(y.shape[1],))
实际应用中可用来训练著名的手写字体数据集 Mnist,10 次迭代后正确率有 98%如果想更简单粗暴点的话:
nn.build([x.shape[1], 24, 24, y.shape[1]])
这定义了一个含两个隐藏层的、每层有 24 个神经元的、以 Sigmoid 为激活函数、以 Cross Entropy 为损失的神经网络
<2>普通的 CNN,只要在上文支持的激活函数、这里都会支持
题图就是一个例子;当然题图那种结构不怎么用于实际(其实也可以用但更多是觉得好玩才定义了诸如 (3, 1) 和 (1, 3) 这样的 Filter……)(但其实这种 Filter 有时很厉害的,这里按下不表)。有如下三个功能是值得一提的:
a. padding 即可以自己定义(对应 tensorflow 中的 VALID)也可以直接用 SAME(默认是 SAME)
b. 支持两种附加层 Dropout 和 Normalize;不仅是在普通神经网络中支持(参见下面的栗子),在 CNN 中也支持(参见下面分形 CNN 中的栗子)
c. 可以用循环体来堆重复的结构,比如:
nn.add("ConvReLU",(x.shape[1:],(32,3,3)))for_inrange(100):
nn.add("ConvReLU",((32,3,3),))nn.add("ReLU",(512,))nn.add("ReLU",(64,))
nn.add("Normalize")nn.add("Dropout")nn.add("CrossEntropy",(y.shape[1],))
当然了,我相信上面这个 103 层的玩意儿不宜使用……但它没 bug(科科)
<3>分形的 CNN,典型例子就是 GooLeNet,下面放出一个长得比较像的实现
a. 用函数体把每一块分形封装起来
defadd_layers(_nn):
_nn.add("Pipe",3)
_nn.add_pipe_layer(0,"ConvReLU",((32,1,3),))
_nn.add_pipe_layer(0,"ConvReLU",((32,3,1),))
_nn.add_pipe_layer(1,"ConvReLU",((32,2,3),))
_nn.add_pipe_layer(1,"ConvReLU",((32,3,2),))
_nn.add_pipe_layer(2,"ConvReLU",((32,1,1),))
_nn.add_pipe_layer(2,"Pipe",2)
_pipe=nn.get_current_pipe(2)
_pipe.add_pipe_layer(0,"ConvReLU",((16,1,3),))
_pipe.add_pipe_layer(1,"ConvReLU",((16,3,1),))
b. 堆!!!
nn.add("ConvReLU",(x.shape[1:],(32,3,3)))nn.add("ConvReLU",((32,3,3),))nn.add("MaxPool",((3,3),),2)nn.add("ConvNorm")add_layers(nn)nn.add("MaxPool",((3,3),),2)nn.add("ConvNorm")add_layers(nn)nn.add("AvgPool",((3,3),),2)nn.add("ConvNorm")add_layers(nn)nn.add("ReLU",(512,))nn.add("ReLU",(64,))nn.add("Normalize")nn.add("CrossEntropy",(y.shape[1],))
<4>可扩展性。个人认为在这方面我还是下了比较大功夫的、所以可扩展性应该算不错。目前的话,用tensorflow 的话支持自定义激活函数,如果用我自己写的 Numpy 算法(大概这东西叫做一个新的 nn 轮子?不太懂相关定义……)的话就还支持自定义 Optimizer。由于使用我自己写的算法来进行扩展的话,虽然自由度更高、但需要更多相关的基础知识,我打算把它放在一个额外的章节来讲,这里就只说怎么在使用 tensorflow 的情况下自定义激活函数吧;经评论区的童鞋提醒,我打算讲两种自定义方式:
a. 在原有的激活函数上修改。比如我觉得 ReLU 在处理输入很大时的方法太豪放了想让它安分一点、给激活后的输出一个上界 6 的话(返回 min(max(x, 0), 6)) (这东西好像叫 ReLU6 ?),我可以这样把原来的 ReLU 类
classReLU(Layer):
def_activate(self,x,predict):
returntf.nn.relu(x)
改成
classReLU(Layer):
def_activate(self,x,predict):
returntf.minimum(tf.maximum(x,0),6)
就行了,同时该激活函数会自动被 ConvReLU、也就是 CNN 中使用的 ReLU 继承是不是相当方便呢 ( σ'ω')σ
b. 可能会有观众老爷说,你这个只是把现有的东西偷偷换了一下,如果我想定义一个属于自己的、名字也是自己随便定的激活函数怎么办?!
不妨将我们新的激活函数叫做 CF0910,它返回的值同样是 min(max(x, 0), 6) :
1. 定义 CF0910 类并继承 Layer 类,同时定义其激活函数:
classCF0910(Layer):
def_activate(self,x,predict):
returntf.minimum(tf.maximum(x,0),6)
2. 在下面的“工厂”里面“注册”一下这个层的信息:
classLayerFactory:
available_root_layers={
"CF0910":CF0910,
...
3. 完了。
是的没错,这就完了!!崭新的激活函数出现了!!拿着它去玩吧观众老爷们!!各种发 Paper 拿大奖不是梦!!(不
有些细心的观众老爷可能会发现:咦你这不是只定义了普通的神经网络层吗?那如果我想把这个激活函数应用到 CNN 里面呢?
嗯,为此你可以这样做:
a. 定义一个继承了各种乱七八糟的东西的类(重点:顺序不能错!)(重点2:继承的第二个类就是刚刚定义的那个类!):
classConvCF0910(ConvLayer,CF0910,metaclass=ConvLayerMeta):
pass
b. 再去工厂注册一下:
classLayerFactory:available_root_layers={
"CF0910":CF0910,"ConvCF0910":ConvCF0910,
...
c.完了。
是不是很棒???(不
夸我吧!赞我吧!!GitHub 上面 star 我吧!!!(喂
那么怎么应用呢?方法是一样一样的:
nn.add("ConvCF0910",(x.shape[1:],(32,3,3)))
for_inrange(100):nn.add("ConvCF0910",((32,3,3),))nn.add("ReLU",(512,))
nn.add("ReLU",(64,))nn.add("Normalize")nn.add("Dropout")nn.add("CrossEntropy",(y.shape[1],))
Again,建议不要真的去跑这个结构……
如果想要了解我自己造的那个自由度很高的轮子的话,欢迎私信或者等我以后的附加章节~
此外,1. 和 2. 的结构是可以保存下来的(3. 的还没写因为感觉好麻烦)(喂):
nn.save()
读取也很方便:
nn.load()
然后可视化也做了一定的工作、包括但不限于:
1.预览结构
2.进度条
3.耗时统计
4.CNN 结果的直观理解
5.以及其它……要说的话我还用 cv2 弄了一个动态的可视化(类似 TensorFlow Playground 那种的),有兴趣可以戳这个最终成品的 GitHub 地址看看~
https://github.com/carefree0910/MachineLearning/tree/master/NN
以上就是一个大概的功能呈现,感觉还是不错的(骄傲脸)(被打飞)
下一章开始就是从零起步了,具体而言会分为三种:
1.Python 的基础,这一部分文章的标题形如 “Python · ***”
2.实现的思想、原理及代码,这一部分的标题就和这一章的类似,随介绍的算法不同而不同
3.数学的基础,这一部分的标题也与这一章类似,只不过前缀改为 “数学 · *** · ***”
4.额外的章节,这些章节的标题形如“Python · 神经网络(二*) · 层”、也就是说章节数的右上角会带一个星号。在这些的章节中,我会介绍我自己写的、只用到 Numpy 的算法,主要目的是服务想了解算法细节的观众老爷们 ( σ'ω')σ
自然,1. 的知识是各机器学习算法实现都共享的,2. 3. 的内容有一定相关性但分开来看不会有什么问题(大概)(喂
希望观众老爷们能够喜欢~
【福利推荐】最案例,金品质!5 In 1机器学习微课,案例实战练真功!
5门课程,一起学习:
课程一:人工智能系列直播之机器学习与工业实践 [讲师:邹博]
课程二:利用 Python 建构金融数据分析平台 [讲师:丘祐玮]
课程三:自然语言处理之-基于深度学习技术的诗歌写作机器人 [讲师:Kenny]
课程四:使用机器学习建立数据模型(关联与频繁样式分析篇) [讲师:丘祐玮]
课程五:数据挖掘快速上手之R语言实践[讲师:谢佳标]