还在纠结垃圾分类问题?用Python感受ImageNet的强大 Image

发布时间:2019-07-24 18:16:01 来源:老男孩IT教育 关键词:Image
Image
原文标题:还在纠结垃圾分类问题?用Python感受ImageNet的强大
原文发布时间:2019-07-08 20:11:00
原文作者:老男孩IT教育。
如果您喜欢本文,请关注头条号【老男孩IT教育】阅读更多相关文章。
如果您是本文作者,不希望我们转载此文,请联系我们删除。
Image

上海正式开始了“史上最严“垃圾分类的规定,扔错垃圾最高可罚200元。全国其它46个城市也要陆续步入垃圾分类新时代。各种被垃圾分类逼疯的段子在社交媒体上层出不穷。

其实从人工智能的角度看垃圾分类就是图像处理中图像分类任务的一种应用,而这在2012年以来的ImageNet图像分类任务的评比中,SENet模型以top-5测试集回归2.25%错误率的成绩可谓是技压群雄,堪称目前最强的图像分类器。

还在纠结垃圾分类问题?用Python感受ImageNet的强大


还在纠结垃圾分类问题?用Python感受ImageNet的强大


笔者刚刚还到SENet的创造者momenta公司的网站上看了一下,他们最新的方向已经是3D物体识别和标定了,效果如下:

还在纠结垃圾分类问题?用Python感受ImageNet的强大

可以说他们提出的SENet进行垃圾图像处理是完全没问题的。


Senet简介

Senet的是由momenta和牛津大学共同提出的一种基于挤压(squeeze)和激励(Excitation)的模型,每个模块通过“挤压”操作嵌入来自全局感受野的信息,并且通过“激励”操作选择性地诱导响应增强。我们可以看到历年的ImageNet冠军基本都是在使用加大模型数量和连接数量的方式来提高精度,而Senet在这种”大力出奇迹”的潮流下明显是一股清流。

其具体原理说明如下:

还在纠结垃圾分类问题?用Python感受ImageNet的强大


Sequeeze:对 C×H×W 进行 global average pooling,得到 1×1×C 大小的特征图,这个特征图可以理解为具有全局感受野。翻译论文原文来说:将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野。

Excitation :使用一个全连接神经网络,对 Sequeeze 之后的结果做一个非线性变换。它的机制一个类似于循环神经网络中的门。通过参数 w 来为每个特征通道生成权重,其中参数 w 被学习用来显式地建模特征通道间的相关性。

特征重标定:使用 Excitation 得到的结果作为权重,乘到输入特征上。将Excitation输出的权重可以认为是特征通道的重要性反应,逐通道加权到放到先前的特征上,完成对原始特征的重标定。

其模型架构如下:

还在纠结垃圾分类问题?用Python感受ImageNet的强大


SENet 构造非常简单,而且很容易被部署,不需要引入新的函数或者层。其caffe模型可以通过百度下载。

Senet的运用

如果读者布署有caffe那么直接下载刚刚的模型直接load进来就可以使用了。如果没有装caffe而装了tensorflow也没关系,我们刚刚说了SENet没有引入新的函数和层,很方便用tensorflow实现。

下载图像集:经笔者各方查找发现了这个数据集,虽然不大也没有发挥出SENet的优势,不过也方便使用:

建立SENet模型:使用tensorflow建立的模型在github上也有开源项目了,网址如下:https://github.com/taki0112/SENet-Tensorflow,只是他使用的是Cifar10数据集,不过这也没关系,只需要在gitclone以下将其cifar10.py中的prepare_data函数做如下修改即可。

 1def prepare_data():
2 print("======Loading data======")
3 download_data()
4 data_dir = 'e:/test/'
5 #data_dir = './cifar-10-batches-py'#改为你的文件侠
6 image_dim = image_size * image_size * img_channels
7 #meta = unpickle(data_dir + '/batches.meta')#本数据集不使用meta文件分类,故需要修改
8 label_names = ['cardboard','glass','metal','trash','paper','plastic']
9 label_count = len(label_names)
10 #train_files = ['data_batch_%d' % d for d in range(1, 6)]
11 train_files = [data_dir+s for s in label_names]#改为
12 train_data, train_labels = load_data(train_files, data_dir, label_count)
13 test_data, test_labels = load_data(['test_batch'], data_dir, label_count)
14
15 print("Train data:", np.shape(train_data), np.shape(train_labels))
16 print("Test data :", np.shape(test_data), np.shape(test_labels))
17 print("======Load finished======")
18
19 print("======Shuffling data======")
20 indices = np.random.permutation(len(train_data))
21 train_data = train_data[indices]
22 train_labels = train_labels[indices]
23 print("======Prepare Finished======")
24
25 return train_data, train_labels, test_data, test_labels

其最主要的建模代码如下,其主要工作就是将SENet的模型结构实现一下即可:

 1import tensorflow as tf
2from tflearn.layers.conv import global_avg_pool
3from tensorflow.contrib.layers import batch_norm, flatten
4from tensorflow.contrib.framework import arg_scope
5from cifar10 import *
6import numpy as np
7
8weight_decay = 0.0005
9momentum = 0.9
10
11init_learning_rate = 0.1
12
13reduction_ratio = 4
14
15batch_size = 128
16iteration = 391
17# 128 * 391 ~ 50,000
18
19test_iteration = 10
20
21total_epochs = 100
22
23def conv_layer(input, filter, kernel, stride=1, padding='SAME', layer_name="conv", activation=True):
24 with tf.name_scope(layer_name):
25 network = tf.layers.conv2d(inputs=input, use_bias=True, filters=filter, kernel_size=kernel, strides=stride, padding=padding)
26 if activation :
27 network = Relu(network)
28 return network
29
30def Fully_connected(x, units=class_num, layer_name='fully_connected') :
31 with tf.name_scope(layer_name) :
32 return tf.layers.dense(inputs=x, use_bias=True, units=units)
33
34def Relu(x):
35 return tf.nn.relu(x)
36
37def Sigmoid(x):
38 return tf.nn.sigmoid(x)
39
40def Global_Average_Pooling(x):
41 return global_avg_pool(x, name='Global_avg_pooling')
42
43def Max_pooling(x, pool_size=[3,3], stride=2, padding='VALID') :
44 return tf.layers.max_pooling2d(inputs=x, pool_size=pool_size, strides=stride, padding=padding)
45
46def Batch_Normalization(x, training, scope):
47 with arg_scope([batch_norm],
48 scope=scope,
49 updates_collections=None,
50 decay=0.9,
51 center=True,
52 scale=True,
53 zero_debias_moving_mean=True) :
54 return tf.cond(training,
55 lambda : batch_norm(inputs=x, is_training=training, reuse=None),
56 lambda : batch_norm(inputs=x, is_training=training, reuse=True))
57
58def Concatenation(layers) :
59 return tf.concat(layers, axis=3)
60
61def Dropout(x, rate, training) :
62 return tf.layers.dropout(inputs=x, rate=rate, training=training)
63
64def Evaluate(sess):
65 test_acc = 0.0
66 test_loss = 0.0
67 test_pre_index = 0
68 add = 1000
69
70 for it in range(test_iteration):
71 test_batch_x = test_x[test_pre_index: test_pre_index + add]
72 test_batch_y = test_y[test_pre_index: test_pre_index + add]
73 test_pre_index = test_pre_index + add
74
75 test_feed_dict = {
76 x: test_batch_x,
77 label: test_batch_y,
78 learning_rate: epoch_learning_rate,
79 training_flag: False
80 }
81
82 loss_, acc_ = sess.run([cost, accuracy], feed_dict=test_feed_dict)
83
84 test_loss += loss_
85 test_acc += acc_
86
87 test_loss /= test_iteration # average loss
88 test_acc /= test_iteration # average accuracy
89
90 summary = tf.Summary(value=[tf.Summary.Value(tag='test_loss', simple_value=test_loss),
91 tf.Summary.Value(tag='test_accuracy', simple_value=test_acc)])
92
93 return test_acc, test_loss, summary
94
95class SE_Inception_resnet_v2():
96 def __init__(self, x, training):
97 self.training = training
98 self.model = self.Build_SEnet(x)
99
100 def Stem(self, x, scope):
101 with tf.name_scope(scope) :
102 x = conv_layer(x, filter=32, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_conv1')
103 x = conv_layer(x, filter=32, kernel=[3,3], padding='VALID', layer_name=scope+'_conv2')
104 block_1 = conv_layer(x, filter=64, kernel=[3,3], layer_name=scope+'_conv3')
105
106 split_max_x = Max_pooling(block_1)
107 split_conv_x = conv_layer(block_1, filter=96, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv1')
108 x = Concatenation([split_max_x,split_conv_x])
109
110 split_conv_x1 = conv_layer(x, filter=64, kernel=[1,1], layer_name=scope+'_split_conv2')
111 split_conv_x1 = conv_layer(split_conv_x1, filter=96, kernel=[3,3], padding='VALID', layer_name=scope+'_split_conv3')
112
113 split_conv_x2 = conv_layer(x, filter=64, kernel=[1,1], layer_name=scope+'_split_conv4')
114 split_conv_x2 = conv_layer(split_conv_x2, filter=64, kernel=[7,1], layer_name=scope+'_split_conv5')
115 split_conv_x2 = conv_layer(split_conv_x2, filter=64, kernel=[1,7], layer_name=scope+'_split_conv6')
116 split_conv_x2 = conv_layer(split_conv_x2, filter=96, kernel=[3,3], padding='VALID', layer_name=scope+'_split_conv7')
117
118 x = Concatenation([split_conv_x1,split_conv_x2])
119
120 split_conv_x = conv_layer(x, filter=192, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv8')
121 split_max_x = Max_pooling(x)
122
123 x = Concatenation([split_conv_x, split_max_x])
124
125 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
126 x = Relu(x)
127
128 return x
129
130 def Inception_resnet_A(self, x, scope):
131 with tf.name_scope(scope) :
132 init = x
133
134 split_conv_x1 = conv_layer(x, filter=32, kernel=[1,1], layer_name=scope+'_split_conv1')
135
136 split_conv_x2 = conv_layer(x, filter=32, kernel=[1,1], layer_name=scope+'_split_conv2')
137 split_conv_x2 = conv_layer(split_conv_x2, filter=32, kernel=[3,3], layer_name=scope+'_split_conv3')
138
139 split_conv_x3 = conv_layer(x, filter=32, kernel=[1,1], layer_name=scope+'_split_conv4')
140 split_conv_x3 = conv_layer(split_conv_x3, filter=48, kernel=[3,3], layer_name=scope+'_split_conv5')
141 split_conv_x3 = conv_layer(split_conv_x3, filter=64, kernel=[3,3], layer_name=scope+'_split_conv6')
142
143 x = Concatenation([split_conv_x1,split_conv_x2,split_conv_x3])
144 x = conv_layer(x, filter=384, kernel=[1,1], layer_name=scope+'_final_conv1', activation=False)
145
146 x = x*0.1
147 x = init + x
148
149 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
150 x = Relu(x)
151
152 return x
153
154 def Inception_resnet_B(self, x, scope):
155 with tf.name_scope(scope) :
156 init = x
157
158 split_conv_x1 = conv_layer(x, filter=192, kernel=[1,1], layer_name=scope+'_split_conv1')
159
160 split_conv_x2 = conv_layer(x, filter=128, kernel=[1,1], layer_name=scope+'_split_conv2')
161 split_conv_x2 = conv_layer(split_conv_x2, filter=160, kernel=[1,7], layer_name=scope+'_split_conv3')
162 split_conv_x2 = conv_layer(split_conv_x2, filter=192, kernel=[7,1], layer_name=scope+'_split_conv4')
163
164 x = Concatenation([split_conv_x1, split_conv_x2])
165 x = conv_layer(x, filter=1152, kernel=[1,1], layer_name=scope+'_final_conv1', activation=False)
166 # 1154
167 x = x * 0.1
168 x = init + x
169
170 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
171 x = Relu(x)
172
173 return x
174
175 def Inception_resnet_C(self, x, scope):
176 with tf.name_scope(scope) :
177 init = x
178
179 split_conv_x1 = conv_layer(x, filter=192, kernel=[1,1], layer_name=scope+'_split_conv1')
180
181 split_conv_x2 = conv_layer(x, filter=192, kernel=[1, 1], layer_name=scope + '_split_conv2')
182 split_conv_x2 = conv_layer(split_conv_x2, filter=224, kernel=[1, 3], layer_name=scope + '_split_conv3')
183 split_conv_x2 = conv_layer(split_conv_x2, filter=256, kernel=[3, 1], layer_name=scope + '_split_conv4')
184
185 x = Concatenation([split_conv_x1,split_conv_x2])
186 x = conv_layer(x, filter=2144, kernel=[1,1], layer_name=scope+'_final_conv2', activation=False)
187 # 2048
188 x = x * 0.1
189 x = init + x
190
191 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
192 x = Relu(x)
193
194 return x
195
196 def Reduction_A(self, x, scope):
197 with tf.name_scope(scope) :
198 k = 256
199 l = 256
200 m = 384
201 n = 384
202
203 split_max_x = Max_pooling(x)
204
205 split_conv_x1 = conv_layer(x, filter=n, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv1')
206
207 split_conv_x2 = conv_layer(x, filter=k, kernel=[1,1], layer_name=scope+'_split_conv2')
208 split_conv_x2 = conv_layer(split_conv_x2, filter=l, kernel=[3,3], layer_name=scope+'_split_conv3')
209 split_conv_x2 = conv_layer(split_conv_x2, filter=m, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv4')
210
211 x = Concatenation([split_max_x, split_conv_x1, split_conv_x2])
212
213 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
214 x = Relu(x)
215
216 return x
217
218 def Reduction_B(self, x, scope):
219 with tf.name_scope(scope) :
220 split_max_x = Max_pooling(x)
221
222 split_conv_x1 = conv_layer(x, filter=256, kernel=[1,1], layer_name=scope+'_split_conv1')
223 split_conv_x1 = conv_layer(split_conv_x1, filter=384, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv2')
224
225 split_conv_x2 = conv_layer(x, filter=256, kernel=[1,1], layer_name=scope+'_split_conv3')
226 split_conv_x2 = conv_layer(split_conv_x2, filter=288, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv4')
227
228 split_conv_x3 = conv_layer(x, filter=256, kernel=[1,1], layer_name=scope+'_split_conv5')
229 split_conv_x3 = conv_layer(split_conv_x3, filter=288, kernel=[3,3], layer_name=scope+'_split_conv6')
230 split_conv_x3 = conv_layer(split_conv_x3, filter=320, kernel=[3,3], stride=2, padding='VALID', layer_name=scope+'_split_conv7')
231
232 x = Concatenation([split_max_x, split_conv_x1, split_conv_x2, split_conv_x3])
233
234 x = Batch_Normalization(x, training=self.training, scope=scope+'_batch1')
235 x = Relu(x)
236
237 return x
238
239 def Squeeze_excitation_layer(self, input_x, out_dim, ratio, layer_name):
240 with tf.name_scope(layer_name) :
241
242
243 squeeze = Global_Average_Pooling(input_x)
244
245 excitation = Fully_connected(squeeze, units=out_dim / ratio, layer_name=layer_name+'_fully_connected1')
246 excitation = Relu(excitation)
247 excitation = Fully_connected(excitation, units=out_dim, layer_name=layer_name+'_fully_connected2')
248 excitation = Sigmoid(excitation)
249
250 excitation = tf.reshape(excitation, [-1,1,1,out_dim])
251 scale = input_x * excitation
252
253 return scale
254
255 def Build_SEnet(self, input_x):
256 input_x = tf.pad(input_x, [[0, 0], [32, 32], [32, 32], [0, 0]])
257 # size 32 -> 96
258 print(np.shape(input_x))
259 # only cifar10 architecture
260
261 x = self.Stem(input_x, scope='stem')
262
263 for i in range(5) :
264 x = self.Inception_resnet_A(x, scope='Inception_A'+str(i))
265 channel = int(np.shape(x)[-1])
266 x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_A'+str(i))
267
268 x = self.Reduction_A(x, scope='Reduction_A')
269
270 channel = int(np.shape(x)[-1])
271 x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_A')
272
273 for i in range(10) :
274 x = self.Inception_resnet_B(x, scope='Inception_B'+str(i))
275 channel = int(np.shape(x)[-1])
276 x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_B'+str(i))
277
278 x = self.Reduction_B(x, scope='Reduction_B')
279
280 channel = int(np.shape(x)[-1])
281 x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_B')
282
283 for i in range(5) :
284 x = self.Inception_resnet_C(x, scope='Inception_C'+str(i))
285 channel = int(np.shape(x)[-1])
286 x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_C'+str(i))
287
288
289 # channel = int(np.shape(x)[-1])
290 # x = self.Squeeze_excitation_layer(x, out_dim=channel, ratio=reduction_ratio, layer_name='SE_C')
291
292 x = Global_Average_Pooling(x)
293 x = Dropout(x, rate=0.2, training=self.training)
294 x = flatten(x)
295
296 x = Fully_connected(x, layer_name='final_fully_connected')
297 return x
298
299
300train_x, train_y, test_x, test_y = prepare_data()
301train_x, test_x = color_preprocessing(train_x, test_x)
302
303
304# image_size = 32, img_channels = 3, class_num = 10 in cifar10
305x = tf.placeholder(tf.float32, shape=[None, image_size, image_size, img_channels])
306label = tf.placeholder(tf.float32, shape=[None, class_num])
307
308training_flag = tf.placeholder(tf.bool)
309
310
311learning_rate = tf.placeholder(tf.float32, name='learning_rate')
312
313logits = SE_Inception_resnet_v2(x, training=training_flag).model
314cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=label, logits=logits))
315
316l2_loss = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables()])
317optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=momentum, use_nesterov=True)
318train = optimizer.minimize(cost + l2_loss * weight_decay)
319
320correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(label, 1))
321accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
322
323saver = tf.train.Saver(tf.global_variables())
324
325with tf.Session() as sess:
326 ckpt = tf.train.get_checkpoint_state('./model')
327 if ckpt and tf.train.checkpoint_exists(ckpt.model_checkpoint_path):
328 saver.restore(sess, ckpt.model_checkpoint_path)
329 else:
330 sess.run(tf.global_variables_initializer())
331
332 summary_writer = tf.summary.FileWriter('./logs', sess.graph)
333
334 epoch_learning_rate = init_learning_rate
335 for epoch in range(1, total_epochs + 1):
336 if epoch % 30 == 0 :
337 epoch_learning_rate = epoch_learning_rate / 10
338
339 pre_index = 0
340 train_acc = 0.0
341 train_loss = 0.0
342
343 for step in range(1, iteration + 1):
344 if pre_index + batch_size < 50000:
345 batch_x = train_x[pre_index: pre_index + batch_size]
346 batch_y = train_y[pre_index: pre_index + batch_size]
347 else:
348 batch_x = train_x[pre_index:]
349 batch_y = train_y[pre_index:]
350
351 batch_x = data_augmentation(batch_x)
352
353 train_feed_dict = {
354 x: batch_x,
355 label: batch_y,
356 learning_rate: epoch_learning_rate,
357 training_flag: True
358 }
359
360 _, batch_loss = sess.run([train, cost], feed_dict=train_feed_dict)
361 batch_acc = accuracy.eval(feed_dict=train_feed_dict)
362
363 train_loss += batch_loss
364 train_acc += batch_acc
365 pre_index += batch_size
366
367
368 train_loss /= iteration # average loss
369 train_acc /= iteration # average accuracy
370
371 train_summary = tf.Summary(value=[tf.Summary.Value(tag='train_loss', simple_value=train_loss),
372 tf.Summary.Value(tag='train_accuracy', simple_value=train_acc)])
373
374 test_acc, test_loss, test_summary = Evaluate(sess)
375
376 summary_writer.add_summary(summary=train_summary, global_step=epoch)
377 summary_writer.add_summary(summary=test_summary, global_step=epoch)
378 summary_writer.flush()
379
380 line = "epoch: %d/%d, train_loss: %.4f, train_acc: %.4f, test_loss: %.4f, test_acc: %.4f \n" % (
381 epoch, total_epochs, train_loss, train_acc, test_loss, test_acc)
382 print(line)
383
384 with open('logs.txt', 'a') as f:
385 f.write(line)
386
387 saver.save(sess=sess, save_path='./model/Inception_resnet_v2.ckpt')


简单易上手的python语言广受欢迎,那么今年python的发展前景到底如何呢↓ ↓ ↓

还在纠结垃圾分类问题?用Python感受ImageNet的强大

视频加载中...

前景一:Linux运维

Linux运维是必须而且一定要掌握Python语言的,Python是一门非常NB的编程语言,它可以满足Linux运维工程师的工作需求提升效率,总而提升自己的能力。运维工程师需要自己独立开发一个完整的自动化系统时,这个时候才是真正价值的体现,才能证明自身的能力。

前景二:Python Web网站工程师

我们都知道Web一直都是不可忽视的存在,我们离不开网络,离不开Web,利用Python的框架可以做网站,而且都是一些精美的前端界面,还有我们需要掌握一些数据的应用。

前景三:Python自动化测试

大家都知道,Python语言对测试的帮助是非常大的,自动化测试中Python语言的用途很广,掌握和熟悉自动化的流程、方法和我们总使用的各个模板,到现在为止,我了解的Python使用最多的应该是自动化测试。

前景四:数据分析

现在大数据的时代已经来临了,数据可以说明一切问题的原因,现在数据分析不像原来那么简单,Python语言成为了做数据分析师的先进优选,它同时可以给工作带来很大的效率。

前景五:人工智能

相信大家都知道谷歌制作出的机器人战胜了一个围棋大师的新闻,这个就是目前刚出头的人工智能的功能,当然我们的人工智能时代还没有到来,如果这天来了,生活和世界将会发生翻天覆地的变化,而且现在发展这么快,人工智能的时代不会太远。

以上就是目前比较好的几个Python的发展规划和前景,作为简单主义思想代表的Python语言,不需要去探究语言本身,只用你专注于问题的解决。担心学不好编程的朋友们,欢迎来中软学习简单易上手的Python。


欢迎关注我们的A站B站,观看更多 Python 相关的技术文章、工具资源、精选课程、热点资讯等。

还在纠结垃圾分类问题?用Python感受ImageNet的强大


正文完,原文标题:还在纠结垃圾分类问题?用Python感受ImageNet的强大
原文发布时间:2019-07-08 20:11:00
原文作者:老男孩IT教育。

Image Image




本文关键词:Image
猜你喜欢