3 months ago

L1范数(向量中各个元素绝对值之和,就是绝对值相加,又称曼哈顿距离),L2范数(就是欧几里德距离)或汉明距离

fast RCNN的简单过程,anchor如何设定

参考资料:
《百面机器学习》读后总结

 
3 months ago

一、需求背景

1.博世灯检机

采用工业相机进行图像采样,用于药液微米级大小的可见微粒分布的检测
常规速度400瓶/分,最大600瓶/分,每瓶最大拍照24张,相机拍摄间隔0.1-0.15s
用于无色安培、有色安剖、有色药液、荧光性液体,
以高速旋转每个容器,然后突然停止,使液体靠惯性运动
采用目前国际上最先进的两种检测技术:
1.SD静态划分透光技术:中低黏度药液
通过透过液体的光致使移动的粒子投射阴影到高分辨率的传感器上
使系统能够检测到中低粘度液体中的可见异物 以及容器的装量
2.基于摄像的(视觉系统)技术设备
采用了最新的CCD电荷耦合视觉技术,生成高清晰度图像,检查高粘度液体中的可见异物、容器的装量以及容器的外观缺陷
如:瓶尖、瓶帽、压边、瓶塞、瓶颈、瓶底、装量、产品的颜色和其 他要求的检验项目

2.杭州展拓智控:机器视觉表面瑕疵高速检测系统

基于机器视觉技术实现对产品表面缺陷实现100%的检测
可广泛应用于烟包、药品、化妆品、标签、药用薄膜、包装薄膜、铝箔、涂层材料、纸张、无纺布和金属薄膜等众多行业领域
其主要原理是利用高速工业线扫描相机对被检品表面的2D图像进行100%的扫描记录
以完美的金图(人工检验无缺陷的图像)作为参照物,由高速计算机系统对实时采集到的图像进行复杂的图像处理分析
将用户所关注的表面缺陷(如印刷领域的刀丝、套印、毛刺、泼墨、糊版等)检测出来

3.山东创典智能:全自动高速瓶盖检测机

使用产品 酒瓶盖,品质检测、防盗盖品质检测、缺陷检测
检测规格 直径29mm 高度:15mm-60mm Diameter: 29mm Height: 15mm-60mm
缺陷检测 1)垫片的脏污、反垫、翘垫、垫片类型判断(泡沫垫片,锡箔垫片,二维码垫片,硅胶垫片,丁基垫片等);
2)瓶口的挤伤、失圆、豁口、褶皱等缺陷3)盖面的刮痕、盖边刮擦、掉、异色混盖
检测精度 0.05mm
检测速度 600 - 800个/分钟(视直径大小,检测内容有差异)
镜头 CCD工业相机,高分辨镜头

4.山东新华:连续旋转式全自动灯检机

在机器内部同一圆周上设置三个成像检测装置:两个成像颗粒检测装置和一个成像表面检测装置
成像颗粒检测装置包括照相机、照明设备和推进器,照相机安装在推进器的滑杆 上,照相机的镜头对向药瓶,推进器顶端垂直设置照明设备,照明设备的光束朝向药瓶底部。
成像表面检测装置的照明设备釆用照明高频两极LED。光线由照明设备产生并从底部 纵向的照亮药瓶,同时照相机在推进器的帮助下,成像检测出药瓶内部影像。照明设备和照 相机可以设置为3套,这样可以使得一定时间内同时对3个药瓶进行照明和检测。
成像表面检测装置包括照相机、照明设备和推进器,照 相机安装在推进器的滑杆上,照相机的镜头对向药瓶,推进器顶端水平设置照明设备,照明 设备的光束朝向药瓶侧面。

二、博世灯检机项目细节

1.摄像机固定,为了保证颗粒大概率出现在影像中,需要药液旋转,摄像机连续采样

以高速旋转容器,然后突然停止,使液体依靠惯性旋转,转速3000rpm,旋转时间控制在5s以内
依据不合格品的检出率的要求确定要摄取的瓶体的序列图像的帧数
帧数越多不合格品的检出率越高,但所用时间也越长,帧数最少两帧,正常8帧/瓶,最大24帧/瓶

2.光源

如果待检瓶中的液体颜色较浅时,光源从该瓶体下方位置照射该瓶体底部:圆柱形激光光源,直径与待检瓶的直径相当
如果待检瓶中液体颜色较深时,使用平板型背光光源从该瓶体侧面位置照射该瓶体

3.相机类型

1.按芯片类型划分
市面上工业相机大多是基于CCD(Charge Coupled Device)或CMOS(Complementary Metal Oxide Semiconductor)芯片的相机
CCD是机器视觉最为常用的图像传感器。它集光电转换及电荷存贮、电荷转移、信号读取于一体,是典型的固体成像器件。
CCD的突出特点是以电荷作为信号,而不同于其它器件是以电流或者电压为信号。
这类成像器件通过光电转换形成电荷包,而后在驱动脉冲的作用下转移、放大输出图像信号。
典型的CCD相机由光学镜头、时序及同步信号发生器、垂直驱动器、模拟/数字信号处理电路组成。
CCD作为一种功能器件,与真空管相比,具有无灼伤、无滞后、低电压工作、低功耗等优点。
CMOS图像传感器的开发最早出现在20世纪70 年代初,90 年代初期,随着超大规模集成电路 (VLSI) 制造工艺技术的发展,CMOS图像传感器得到迅速发展。
CMOS图像传感器将光敏元阵列、图像信号放大器、信号读取电路、模数转换电路、图像信号处理器及控制器集成在一块芯片上,还具有局部像素的编程随机访问的优点。
CMOS图像传感器以其良好的集成性、低功耗、高速传输和宽动态范围等特点在高分辨率和高速场合得到了广泛的应用。
2.按照传感器的结构特性可以分为线阵相机、面阵相机
线阵相机
3.按照扫描方式可以分为隔行扫描相机、逐行扫描相机;
逐行扫描相机
4.按照分辨率大小可以分为普通分辨率相机、高分辨率相机;
高分辨率相机
5.按照输出信号方式可以分为模拟相机、数字相机;
数字相机
6.按照输出色彩可以分为单色(黑白)相机、彩色相机;
单色相机
7.按照输出信号速度可以分为普通速度相机、高速相机;
一般工业相机快门速度可到10ms,高速相机会更快
8.按照响应频率范围可以分为可见光(普通)相机、红外相机、紫外相机等。
可见光、红外相机

3.相机的分辨率

视野大小:20 x 120 mm,精度要求0.02mm/pixel,软件的测量精度可以考虑1/2亚像素精度
20/0.02/2=1000,120/0.02/2=6000
所以相机至少采用600万像素以上,分辨率至少6000x1000

参考资料:
展拓智控:高速工业线扫描相机应用案例
百度百科:高速相机
中国灯检机行业时长产品价格走势分析
博世灯检机图片展示
山东创典智能 产品展示
博世灯检机 技术参数
山东新华专利:连续旋转式全自动灯检机
专利:瓶装液体中异物的自动检测方法
博世推出新一代全自动检测机AIM 8系列

 
3 months ago

一、原因

两种情况下梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。
梯度爆炸一般出现在深层网络和权值初始化值太大的情况下。

二、如何改进

1.权重正则化:l1正则,l2正则
2.采用relu、leakrelu、elu等激活函数
3.批量归一化 Batch Normalization
4.深度残差网络
5.LSTM长短期记忆网络

参考资料:
详解机器学习中的梯度消失、爆炸原因及其解决方法
如何解决梯度消失和梯度爆炸

 
3 months ago

一、边缘检测

1.边缘检测是图像处理和计算机视觉中的基本问题
边缘检测的目的是标识数字图像中亮度变化明显的点,表现出来的就是图像的轮廓。
图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。 特征提取,降维
2.边缘检测方法很多,绝大部分可以划分为两类:基于查找一类和基于零穿越的一类
基于搜索的边缘检测方法首先计算边缘强度, 通常用一阶导数表示
基于零交叉的方法找到由图像得到的二阶导数的零交叉点来定位边缘
3.边缘检测算子


上面的图像是图像中水平方向7个像素点的灰度值显示效果
我们很容易地判断在第4和第5个像素之间有一个边缘,因为它俩之间发生了强烈的灰度跳变。
在实际的边缘检测中,边缘远没有上图这样简单明显,我们需要取对应的阈值来区分出它们,即所谓的算子。
一阶:Roberts Cross算子,Prewitt算子,Sobel算子, Kirsch算子,罗盘算子;
二阶: Marr-Hildreth,在梯度方向的二阶导数过零点,Canny算子,Laplacian算子。

其中,Canny边缘检测方法常被誉为边缘检测的最优方法,从上图中也可以明显看出效果
这些算子理论看起来很复杂,实际上就是一行代码解决,不信你看

img = cv2.imread('handwriting.jpg', 0)
edges = cv2.Canny(img, 30, 70)  # canny边缘检测

二、区域提取

matlab/python+opencv提取圆形鱼眼图片的有效区域

三、低通滤波

低通滤波(Low-pass filter) 是一种过滤方式,规则为低频信号能正常通过,而超过设定临界值的高频信号则被阻隔、减弱。
但是阻隔、减弱的幅度则会依据不同的频率以及不同的滤波程序(目的)而改变。
它有的时候也被叫做高频去除过滤(high-cut filter)或者最高去除过滤(treble-cut filter)。
低通过滤是高通过滤的对立。

四、二值化

图像二值化将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。
在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。
OpenCV中有两个函数可以实现图片的二值化:

(1)cvThreshold( dst, dst,230 , 255, CV_THRESH_BINARY_INV);
(2)cvAdaptiveThreshold( dst, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY, 9, -10);

五、对比度增强

众所周知,人眼对高频信号(边缘处等)比较敏感。虽然细节信息往往是高频信号,但是他们时常嵌入在大量的低频背景信号中,从而使得其视觉可见性降低。因此适当的提高高频部分能够提高视觉效果并有利于诊断。

对比度增强是将图像中的亮度值范围拉伸或压缩成显示系统指定的亮度显示范围,从而提高图像全部或局部的对比度。
输入图像中的每个亮度值通过一定的转换函数,对应于输出图像的一个显示值。

医学图像由于本身及成像条件的限制,图像的对比度很低,所以医学图像常使用对比度增强
这种增强算法一般都遵循一定的视觉原则

六、OpenCv

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法
可以运行在Linux、Windows、Android和Mac OS操作系统上
它轻量级而且高效---由一系列C函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口。

参考资料:
百度百科:边缘检测
边缘检测
数字图像 - 边缘检测原理 - Sobel, Laplace, Canny算子
Python+OpenCV教程11:边缘检测
百度百科:图像二值化
百度百科:对比度增强
对比度增强算法
图像的局部对比度增强算法

 
3 months ago

背景知识:个性化推荐
通过对用户行为和商品属性进行分析、挖掘,发现用户的个性化需求与兴趣特定,推荐用户可能感兴趣的信息或商品
不同于搜索引擎根据用户需求被动返回,推荐系统是根据用户历史行为主动为用户提供精准的推荐信息

一、传统推荐类型

内容过滤推荐和协同过滤推荐,在不同的应用场景下存在一定局限性

1.内容过滤推荐Content-based Recommendation

为用户推荐其感兴趣商品的相似商品
缺少用户评价信息的利用,不能有效为新用户推荐

2.协同过滤推荐Collaborative Filtering Recommendation

计算目标用户与其他用户的相似度,预测目标用户对特定商品的喜好程度,为用户提供其未见过的产品
应用最广泛的推荐方法之一,有多个子类:基于用户(User-Based)的推荐,基于物品(Item-Based)的推荐,基于社交网络关系(Social-Based)的推荐,基于模型(Model-Based)的推荐等。
对于历史数据稀疏的用户难以起到作用

3.混合推荐

实际工程应用中多采用混合推荐:将多个算法或推荐系统但也组合在一起的技术
各个组成部门可以想流水线一样串行连接,也可以冰箱运行然后一同输出结果
Robin Burke的《Hybrid Recommender Systems:Survey and Experiments》中,将混合推荐方法划分为7中不同的混合策略:
1)加权:对多种推荐预测结果加权求和作为最终推荐预测结果
2)变换:根据不同对问题背景和实际情况,变换选择不同的推荐方法
3)交叉混合:同时采用多种推荐方法给出多种推荐预测结果供用户参考、决策
4)特征组合:对来自不同推荐数据源的特征进行组合,再应用到另一种推荐方法中
5)层叠:先选用一种推荐方法产生粗糙的推荐预测结果,在此推荐结果的基础上使用第二张推荐方法产生较精确的推荐结果
6)特征扩充:一种推荐方法产生的特征信息补充到另一种推荐方法的特征输入中
7)元级别:一种推荐方法产生的模型的作为另一种推荐方法的输入

二、深度学习推荐方法

1)YouTube深度神经网络推荐系统

该系统为超过10亿用户从不断增长的视频库中推荐个性化内容,系统由两个神经网络组成
候选生成网络:从百万量级的视频库中生成上百个候选
排序网络:对候选进行打分排序,输出排名最高对数十个结果

1.候选生成网络

对于一个YouTube用户,可以选用的类别包括两种:
(1)历史行为信息:用户观看历史(视频ID)、搜索词记录(search tokens)等
(2)用户属性信息:人口学信息(地理位置、登陆设备等)、二值特征(性别、是否登陆)、连续特征(年龄等)
通过上述分类类别,推荐系统对视频库中所有视频进行分类,得到每一类对分类结果(即每一个视频对推荐概率),最终输出概率较高对几百个视频
下面介绍候选生成网络的主要运行过程
(1)将用户历史行为信息映射为向量后取平均值得到固定长度的表示;同时,输入用户属性信息中的人口学信息,并将二值特征和连续特征进行归一化处理,用以优化新用户的推荐效果
(2)将所有特征表示拼接为一个特征向量,并输入给非线性多层感知机(MLP,即多个卷积+激活)处理
(3)MLP的输出分别流向训练和预测两个模块。
训练模块:MLP的输出流向softmax分类层,与所有视频特征一同做分类
预测模块:计算MLP的输出(用户综合特征)与所有视频的相似度,取相似度最高的K个输出视频作为预测结果

三、CTR预估:Click-Through-Rate,点击通过率

通过对CTR对预估来衡量推荐效果的好坏
2.广告推荐系统

三.命名实体识别(NER)

命名实体识别的任务就是识别出待处理文本中三大类(实体类、时间类和数字类)、七小类(人名、机构名、地名、时间、日期、货币和百分比)命名实体。
举个简单的例子,在句子“小明早上8点去学校上课。”中,对其进行命名实体识别,应该能提取信息

人名:小明,时间:早上8点,地点:学校。

参考资料:
混合推荐技术总结
谷歌技术论文:用于YouTube推荐的深度神经网络
NLP入门(四)命名实体识别(NER)

 
3 months ago

tensorflow serving用于模型部署,可以保持Server端的API不变的情况下,进行模型热更新,服务器都无需重启即可生效
1、对于开发模型开发者来说
整个项目将训练模型与使用模型进行最大程度解耦合,使得开发者更多关注于模型的代码训练逻辑,以及跟多的时间去更新新的模型,而不需要当心模型的使用逻辑。
开发者只需要把最新的模型上传到服务器,tensorflow serving会自动检测到新模型,
2、对于用户、平台使用
只需要关注使用模型的输入和输出,以及处理的逻辑,不用关心模型的稳定性,是否接口替换。
最直观的感受就是不需要频繁更新软件


导出的模型使用protobuffer协议,tensorflow serving把模型部署后提供两种接口:grpc,restfull
grpc风格:需要去解析grpc协议
restfull风格:直接线上使用,直接与客户端进行交互

 
3 months ago

程序运行过程中,所有变量都是在内存中。一旦程序结束,变量所占用内存就被操作系统回收

一、序列化:把变量从内存中变成可存储或传输的过程

在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
Python提供了pickle模块来实现序列化。

1.首先尝试把一个对象序列化并写入文件

>>> import pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d)
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'

pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。

2.也可以使用pickle.dump()直接把对象序列化后写入一个file-like Object

>>> f = open('dump.txt', 'wb')
>>> pickle.dump(d, f)
>>> f.close()

看看写入的dump.txt文件,一堆乱七八糟的内容,这些都是Python保存的对象内部信息。

二、反序列化:把变量内容从序列化对象重新读到内存里

当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象
也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象。
我们打开另一个Python命令行来反序列化刚才保存的对象:

>>> f = open('dump.txt', 'rb')
>>> d = pickle.load(f)
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}

参考资料:
廖雪峰:序列化

 
4 months ago

之前在介绍RNN网络时对LSTM网络结构有了简单介绍,但是看起来云里雾里,不太明白,今天找到更清楚的解释
我们先来看一下传统的经典的结构示意图



这两张图能够直观地表示出RNN和LSTM的网络结构的复杂程度,但是具体的计算过程和公式没有表达清楚
这里有一个清楚的计算过程,首先看RNN

接下来就是LSTM



中间复杂的网络结构可以用这样一张经典的图进行解释

存储器单元由四个主要元件组成:输入门,具有自回归连接的神经元(与其自身的连接),忘记门和输出门。
自回归连接的权重为1.0,并确保在禁止任何外部干扰的情况下,存储器单元的状态可以从一个时间步长保持恒定到另一个时间步长。
门用于调节存储器单元本身与其环境之间的相互作用。
输入门It、Jt可以允许输入信号改变存储器单元的状态或阻止它:要不要被输入信息影响
输出门Ot可以允许存储器单元的状态对其他神经元产生影响或阻止它:要不要去影响其他神经元
遗忘门Ft可以调整存储器单元的自我重复连接,允许单元根据需要记住或忘记其先前的状态:怎样被之前的状态影响

注:第二份参考资料里面还有介绍GRU网络结构,也相当不错

参考资料:
【深度学习】递归神经网络RNN
An Empirical Exploration of Recurrent Network Architectures
用于情感分析的LSTM网络
理解 LSTM(Long Short-Term Memory, LSTM) 网络

 
4 months ago

之前简单体验了一次keras,这次来进行一些深度体验
由于keras已经被tensorflow收编为高级API,果断在tensorflow的基础上使用keras

一、keras简单使用步骤


整个步骤看起来很多,其实最复杂的就是前面两步,其余步骤都是一行代码的问题

1.定义网络

先定义一个时序模型,然后就可以添加一个或多个网络层

import tensorflow as tf
model = tf.keras.Sequential()

添加各种网络层

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation=tf.nn.relu))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))

全连接层之前别忘了Flatten,这是一个超级大坑

2.编译模型

指定模型使用的loss函数和optimizer函数

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

3.拟合网络:使用训练集训练网络

model.fit(x_train, y_train, epochs=5, batch_size=32)

当然也可以手动分批次训练网络(有了上面的batch-size,相信没人这么清闲吧)

model.train_on_batch(x_batch, y_batch)

4.评估网络:使用测试集数据进行评估

model.evaluate(x_test, y_test)

5.进行预测

使用新数据进行预测

model.predict(x_test, batch_size=32)

二、keras构建一个简单的LSTM网络,预测电影类别

根据电影的描述信息,预测电影感情基调是positive或negtive
keras内置的数据集IMDB,已经转换为深度学习模式适用的格式:单词已经被替换为整数,代表每个单词在该数据集中的有序频率

import numpy
import tensorflow as tf

tf.reset_default_graph()
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
imdb=tf.keras.datasets.imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# 使用keras进行计算时,输入数组必须拥有相同长度,实际每个序列内容不一样长
# 所以进行零填充:将每条影评限制为500词,不足500词的用0填充,长于500词的截短
max_review_length = 500
X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, maxlen=max_review_length)

# create the model
embedding_vector_length = 32
model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(top_words, embedding_vector_length, input_length=max_review_length))

model.add(tf.keras.layers.LSTM(100,input_shape=(X_train[1],1),return_sequences=True))
# 记得在全连接层之前加上Flatten层,不然一直报错
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary()) #收集参数

model.fit(X_train, y_train, epochs=3, batch_size=64)

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)

print("Accuracy: %.2f%%" % (scores[1]*100))

整个训练过程参数变化比较清楚

三、LSTM之前加上卷积层

卷积层负责空间上的特征提取,LSTM负责时间序列上的特征提取

import numpy
import tensorflow as tf

tf.reset_default_graph()
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
imdb=tf.keras.datasets.imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# truncate and pad input sequences
max_review_length = 500
X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, maxlen=max_review_length)

# create the model
embedding_vector_length = 32
model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(top_words, embedding_vector_length, input_length=max_review_length))
# 增加卷积层,卷积核尺寸(3,3,1,32)
model.add(tf.keras.layers.Conv1D(padding="same", activation="relu", kernel_size=3, filters=32))
model.add(tf.keras.layers.MaxPooling1D()) #最大池化层

model.add(tf.keras.layers.LSTM(100,return_sequences=True)) # LSTM层,100个神经元
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

model.fit(X_train, y_train, epochs=3, batch_size=64)

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)

print("Accuracy: %.2f%%" % (scores[1]*100))

训练过程也很正常

四、卷积层后加入多层LSTM

import numpy
import tensorflow as tf

tf.reset_default_graph()
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
imdb=tf.keras.datasets.imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# truncate and pad input sequences
max_review_length = 500
X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, maxlen=max_review_length)

# create the model
embedding_vector_length = 32
model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(top_words, embedding_vector_length, input_length=max_review_length))
model.add(tf.keras.layers.Conv1D(padding="same", activation="relu", kernel_size=3, filters=32))
model.add(tf.keras.layers.MaxPooling1D())

model.add(tf.keras.layers.LSTM(32, return_sequences=True))
model.add(tf.keras.layers.LSTM(24, return_sequences=True))
model.add(tf.keras.layers.LSTM(1,  return_sequences=False))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

model.fit(X_train, y_train, epochs=3, batch_size=64)

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)

print("Accuracy: %.2f%%" % (scores[1]*100))

训练过程也很正常

五、调试中的报错

在同一个文件中反复调试的过程中会出现一个报错

---> model.fit(X_train, y_train, epochs=3, batch_size=64)
TypeError: Cannot interpret feed_dict key as Tensor: Tensor Tensor("embedding_1_input:0", shape=(?, 500), dtype=float32) is not an element of this graph.     

问题出现在sess.run()时,实参赋值给形参出现问题:实参不在本次运算图形中
新建一个文件后运行代码即正常
个人理解是命名空间的问题:原来的实参运行好好的,人为中断后相关资源没有及时释放,再次运行后出现命名冲突

参考资料:
三个老外 《TensorFlow深度学习》
keras中文文档
【深度学习】Keras与TPU初体验
imdb-lstm官方代码
imdb-lstm代码解读

 
4 months ago

一、原始数据处理

先从官网是下载数据集后,是一个文本文档


打开文本后观察数据样式

数据总共两列,第一列是标签:ham表示非垃圾短信,spam表示垃圾短信
第二列表示具体短信内容,长度不定,包含了各种字母、数字、大小写等特殊符号
这样的原始数据处理其实就简单了,先把标签和训练内容单独分开(为演示方便,只取前三个数据)

发现数据与数据之间是通过回车符“\n"隔开的,数据内部的标签和内容是通过制表符“\t”隔开
先把数据与数据分开

在把标签和内容分开

其实还有一些数据清洗的工作

for i in contents:
        # 去除空白字符、下划线、数字(暂时还没想明白这一操作的必要性)
    text_string1 = re.sub(r'([^\s\w]|_|[0-9])+', '', i)
    # 刚刚得到的结果是包含多个元素的列表,要拼接回一个字符串
    text_string2 = " ".join(text_string1.split())
    # 字符统一成小写
    text_string3 = text_string2.lower()

参考资料:
垃圾短信数据集官方下载地址
短信标签:ham、spam解释
Python split()方法
python中的三元表达式