利用keras使用图片生成器来自动载入并基于目录为文件打标签来创建一个神经网络,构建人马分类器
导读
准备数据集下载图片下载文件的代码解压压缩文件浏览文件打印参与训练的图片数量
在数据集随机展示小部分图片设置matplot参数展示图片
Tensorflow中的图片生成器特性实例化一个生成器
设计神经网络构建模型模型结构展示编译模型模型训练代码模型训练过程展示模型测试代码测试结果①测试的第一幅图像及结果②测试的第二幅图像及结果
卷积过程的可视化
准备数据集
考虑数据集不均匀的情况(更接近实际情况),首先下载包含马和人的数据的压缩文件
下载图片
下载文件的代码
!wget
--no
-check
-certificate \
https
://storage
.googleapis
.com
/laurencemoroney
-blog
.appspot
.com
/horse
-or-human
.zip \
-O
/tmp
/horse
-or-human
.zip
解压压缩文件
解压到这个虚拟机的缓存目录
import os
import zipfile
local_zip
= '/tmp/horse-or-human.zip'
zip_ref
= zipfile
.ZipFile
(local_zip
, 'r')
zip_ref
.extractall
('/tmp/horse-or-human')
zip_ref
.close
()
zip文件包含两个子目录,解压后就已经创建好了
train_horse_dir
= os
.path
.join
('/tmp/horse-or-human/horses')
train_human_dir
= os
.path
.join
('/tmp/horse-or-human/humans')
浏览文件
train_horse_names
= os
.listdir
(train_horse_dir
)
print(train_horse_names
[:10])
train_human_names
= os
.listdir
(train_human_dir
)
print(train_human_names
[:10])
[‘horse34-9.png’, ‘horse33-0.png’, ‘horse31-9.png’, ‘horse27-7.png’, ‘horse06-1.png’, ‘horse50-5.png’, ‘horse21-9.png’, ‘horse36-1.png’, ‘horse18-2.png’, ‘horse02-4.png’] [‘human10-26.png’, ‘human04-24.png’, ‘human16-06.png’, ‘human17-25.png’, ‘human04-13.png’, ‘human04-28.png’, ‘human16-22.png’, ‘human07-23.png’, ‘human17-05.png’, ‘human13-09.png’] 可用于生成标签,但是如果用keras生成器的话就不需要了
打印参与训练的图片数量
print('total training horse images:', len(os
.listdir
(train_horse_dir
)))
print('total training human images:', len(os
.listdir
(train_human_dir
)))
total training horse images: 500 total training human images: 527
在数据集随机展示小部分图片
设置matplot参数
%matplotlib inline
import matplotlib
.pyplot
as plt
import matplotlib
.image
as mpimg
nrows
= 4
ncols
= 4
pic_index
= 0
展示图片
fig
= plt
.gcf
()
fig
.set_size_inches
(ncols
* 4, nrows
* 4)
pic_index
+= 8
next_horse_pix
= [os
.path
.join
(train_horse_dir
, fname
)
for fname
in train_horse_names
[pic_index
-8:pic_index
]]
next_human_pix
= [os
.path
.join
(train_human_dir
, fname
)
for fname
in train_human_names
[pic_index
-8:pic_index
]]
for i
, img_path
in enumerate(next_horse_pix
+next_human_pix
):
sp
= plt
.subplot
(nrows
, ncols
, i
+ 1)
sp
.axis
('Off')
img
= mpimg
.imread
(img_path
)
plt
.imshow
(img
)
plt
.show
()
这里有8匹马和8个人,这个数据集的所有图片都是计算机生成的
Tensorflow中的图片生成器
特性
指向一个目录,然后它的子目录自动生成标签 考虑上面这个目录结构,图像目录下有训练和验证的子目录,当把马和人的子目录放在这些目录中,并在其中存储必要图像时,图片生成器可以为这些图片创建一个Feeder,并且为你自动标记。 例如,在训练目录指向一个图片生成器,标签将是马和人,并且每个目录中的图片将会加载并且相应标记。
实例化一个生成器
from tensorflow
.keras
.preprocessing
.image
import ImageDataGenerator
train_datagen
= ImageDataGenerator
(rescale
=1./255)
train_generator
= train_datagen
.flow_from_directory
(
train_dir
,
target_size
=(300,300),
batch_size
=128,
class_mode
='binary')
test_datagen
= ImageDataGenerator
(rescale
=1./255)
validation_generator
= test_datagen
.flow_from_directory
(
validation_dir
,
target_size
=(300,300),
batch_size
=32,
class_mode
='binary')
设计神经网络
构建模型
模型采用顺序排列 这次图片的清晰度高,(300*300),所以进行了三次压缩
model
= tf
.keras
.models
.Sequential
([
tf
.keras
.layers
.Conv2D
(16,(3,3),activation
='relu',
input_shape
=(300,300,3)),
tf
.keras
.layers
.MaxPooling2D
(2,2),
tf
.keras
.layers
.Conv2D
(32,(3,3),activation
='relu'),
tf
.keras
.layers
.MaxPooling2D
(2,2),
tf
.keras
.layers
.Conv2D
(64,(3,3),activation
='relu'),
tf
.keras
.layers
.MaxPooling2D
(2,2),
tf
.keras
.layers
.Flatten
(),
tf
.keras
.layers
.Dense
(512,activation
='relu'),
tf
.keras
.layers
.Dense
(1,activation
='sigmoid')
])
模型结构展示
编译模型
from tensorflow
.keras
.optimizers
import RMSprop
model
.compile(loss
='binary_crossentropy',
optimizer
=RMSprop
(lr
=0.001),
metrics
=['acc'])
模型训练代码
history
= model
.fit_generator
(
train_generator
,
steps_per_epoch
=8,
epochs
=15,
validation_data
=validation_generator
,
validation_steps
=8,
verbose
=2)
模型训练过程展示
模型测试代码
import numpy
as np
from google
.colab
import files
from keras
.preprocessing
import image
uploaded
= files
.upload
()
for fn
in uploaded
.keys
():
path
= '/content/' + fn
img
= image
.load_img
(path
,target_size
=(300,300))
x
= image
.img_to_array
(img
)
x
= np
.expand_dims
(x
,axis
=0)
images
= np
.vstack
([x
])
classes
= model
.predict
(images
,batch_size
=10)
print(classes
[0])
if classes
[0]>0.5:
print(fn
+ "is a human")
else:
print(fn
+ "is a horse")
测试结果
①测试的第一幅图像及结果
②测试的第二幅图像及结果
卷积过程的可视化
import numpy
as np
import random
from tensorflow
.keras
.preprocessing
.image
import img_to_array
, load_img
successive_outputs
= [layer
.output
for layer
in model
.layers
[1:]]
visualization_model
= tf
.keras
.models
.Model
(inputs
= model
.input, outputs
= successive_outputs
)
horse_img_files
= [os
.path
.join
(train_horse_dir
, f
) for f
in train_horse_names
]
human_img_files
= [os
.path
.join
(train_human_dir
, f
) for f
in train_human_names
]
img_path
= random
.choice
(horse_img_files
+ human_img_files
)
img
= load_img
(img_path
, target_size
=(300, 300))
x
= img_to_array
(img
)
x
= x
.reshape
((1,) + x
.shape
)
x
/= 255
successive_feature_maps
= visualization_model
.predict
(x
)
layer_names
= [layer
.name
for layer
in model
.layers
]
for layer_name
, feature_map
in zip(layer_names
, successive_feature_maps
):
if len(feature_map
.shape
) == 4:
n_features
= feature_map
.shape
[-1]
size
= feature_map
.shape
[1]
display_grid
= np
.zeros
((size
, size
* n_features
))
for i
in range(n_features
):
x
= feature_map
[0, :, :, i
]
x
-= x
.mean
()
x
/= x
.std
()
x
*= 64
x
+= 128
x
= np
.clip
(x
, 0, 255).astype
('uint8')
display_grid
[:, i
* size
: (i
+ 1) * size
] = x
scale
= 20. / n_features
plt
.figure
(figsize
=(scale
* n_features
, scale
))
plt
.title
(layer_name
)
plt
.grid
(False)
plt
.imshow
(display_grid
, aspect
='auto', cmap
='viridis')