码了SOFM(Self Organized Feature Mapping)代码,课上演示结束,通常要进行复盘。本篇博文谈谈绘图的一个问题。代码最终要显示原始数据和权值更新(此处不对算法进行说明)后的数据,姑且表示为A和B。

首先遇到的一个问题,关于数据拷贝的问题。

A是ndarray类型,也就是matrix类型。使用

B = A.copy()

将B作为A的数据副本,此时对A的更新不会影响到B。而直接赋值,如:

B = A

A,B是指向同一块内存区域的。同样切片操作也是指向相同区域。也就是说,对ndarray类型的数据要想实现数据拷贝,需要显示调用copy()函数

对于列表的拷贝,直接赋值同样和原始变量指向同一块内存区域,要实现数据拷贝,请使用切片slice(此处不同于ndarray类型)。

第二个问题是关于绘图。代码需求要画出多幅图像的时候怎样处理?先上代码:

原始的思路是采用列表结构,由于列表结构中存放的数据类型一致,直接放数据,使得图像名称和数据分离,没有实现代码解耦,添加新的打印图像的时候,需要在scatterDats()中显式添加图像名称。

于是,一个直接的想法是:将图像名称和数据绑定。但是此时需要考虑字典是无序的,也就是说虽然按顺序加入了要打印的图像,结果显示却是乱序。解决方案是OrderedDict数据结构,意如其名。

第三个问题是,变量命名问题。

为了设置调试开关,原来使用的是

DEBUG=True

其实更好的表达是:

verbose=True

为了表达迭代次数,原来是:

iterNums

更好的表达:

epoch

实际上epoch和iteration也是有区别的。

结合上篇写BP代码的编程复盘,这次的代码风格如下:

从封装角度来说,main函数中基本实现了自己想要的样子。可是高质量的代码,依然路途遥远,心向往之。