├── .idea
├── deployment.xml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── sever.iml
└── workspace.xml
├── README.md
├── __pycache__
├── data_process.cpython-36.pyc
├── flask_sever.cpython-36.pyc
├── prediction.cpython-36.pyc
└── prediction.cpython-37.pyc
├── data_process.py
├── flask_sever.py
├── garbage_classify
└── garbage_classify_rule.json
├── models
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-36.pyc
│ ├── model.cpython-36.pyc
│ └── resnet50.cpython-36.pyc
├── model.py
├── resnet50.py
└── resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5
├── prediction.py
├── run.py
├── start.sh
├── static
└── images
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── banana.jpg
│ ├── box.jpg
│ ├── cigar.jpg
│ ├── egg.jpg
│ ├── img_url.png
│ ├── test.jpg
│ └── test1.jpg
├── templates
└── predict.html
└── test_image
├── test.jpg
└── test1.jpg
/.idea/deployment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/sever.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 | 1574834516325
188 |
189 |
190 | 1574834516325
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #环境初始化
2 | - python3
3 | - 安装框架flask`pip3 install flask`
4 | - 安装tensorflow,keras等依赖
5 | > - `pip3 install tensorflow==1.13.1`
6 | > - `pip3 install keras==2.3.1 `
7 | > - `pip3 install opencv-python `
8 | > - `pip3 install requests `
9 | > - `pip3 install Pillow `
10 |
11 | #运行
12 | - 1.命令`python3 run.py`开启窗口本地调试
13 | - 2.命令`python3 flask_sever.py`开启服务部署
14 | - 3.命令`sh ./start.sh`开启后台运行服务部署
15 |
--------------------------------------------------------------------------------
/__pycache__/data_process.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/__pycache__/data_process.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/flask_sever.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/__pycache__/flask_sever.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/prediction.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/__pycache__/prediction.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/prediction.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/__pycache__/prediction.cpython-37.pyc
--------------------------------------------------------------------------------
/data_process.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | from PIL import Image
3 | import requests as req
4 | from io import BytesIO
5 | import numpy as np
6 | import os
7 | import math
8 | import codecs
9 | import random
10 | from models.resnet50 import preprocess_input
11 |
12 |
13 | # 本地路径获取图片信息
14 | def preprocess_img(img_path, img_size):
15 | try:
16 | img = Image.open(img_path)
17 | # if img.format:
18 | # resize_scale = img_size / max(img.size[:2])
19 | # img = img.resize((int(img.size[0] * resize_scale), int(img.size[1] * resize_scale)))
20 | img = img.resize((256, 256))
21 | img = img.convert('RGB')
22 | # img.show()
23 | img = np.array(img)
24 | imgs = []
25 | for _ in range(10):
26 | i = random.randint(0, 32)
27 | j = random.randint(0, 32)
28 | imgg = img[i:i + 224, j:j + 224]
29 | imgg = preprocess_input(imgg)
30 | imgs.append(imgg)
31 | return imgs
32 | except Exception as e:
33 | print('发生了异常data_process:', e)
34 | return 0
35 |
36 |
37 | # url获取图片数组信息
38 | def preprocess_img_from_Url(img_path, img_size):
39 | try:
40 | response = req.get(img_path)
41 | img = Image.open(BytesIO(response.content))
42 | img = img.resize((256, 256))
43 | img = img.convert('RGB')
44 | # img.show()
45 | img = np.array(img)
46 | imgs = []
47 | for _ in range(10):
48 | i = random.randint(0, 32)
49 | j = random.randint(0, 32)
50 | imgg = img[i:i + 224, j:j + 224]
51 | imgg = preprocess_input(imgg)
52 | imgs.append(imgg)
53 | return imgs
54 | except Exception as e:
55 | print('发生了异常data_process:', e)
56 | return 0
57 |
--------------------------------------------------------------------------------
/flask_sever.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify, render_template
2 |
3 | app = Flask(__name__)
4 | from prediction import prediction_result_from_img, init_artificial_neural_network
5 | from tensorflow.python.keras.backend import set_session
6 | import tensorflow as tf
7 | import os
8 | from werkzeug.utils import secure_filename
9 |
10 | # 程序开始时声明
11 | sess = tf.Session()
12 | graph = tf.get_default_graph()
13 | model = init_artificial_neural_network(sess)
14 | # 设置允许的文件格式
15 | ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp', 'jpeg'])
16 |
17 |
18 | def allowed_file(filename):
19 | return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
20 |
21 |
22 | @app.route('/predict', methods=['POST', 'GET'])
23 | def getclass():
24 | if request.method == 'POST':
25 | f = request.files['file']
26 | if not (f and allowed_file(f.filename)):
27 | return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp,jpeg"})
28 | # user_input = request.form.get("name")
29 | basepath = os.path.dirname(__file__) # 当前文件所在路径
30 | upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
31 | # upload_path = os.path.join(basepath, 'static/images','test.jpg') #注意:没有的文件夹一定要先创建,不然会提示没有该路径
32 | f.save(upload_path)
33 | try:
34 | with graph.as_default():
35 | set_session(sess)
36 | print(upload_path)
37 | res = prediction_result_from_img(model, upload_path)
38 | resp = jsonify({'result': res})
39 | return resp
40 | except Exception as e:
41 | print('发生了异常-getclass:', e)
42 | return jsonify({"error": 1002, "msg": "'发生了异常-getclass" + e})
43 | return render_template('predict.html')
44 |
45 |
46 | @app.route('/', methods=['POST', 'GET'])
47 | def index():
48 | return render_template('predict.html')
49 |
50 |
51 | if __name__ == '__main__':
52 | app.run(host="0.0.0.0")
53 |
--------------------------------------------------------------------------------
/garbage_classify/garbage_classify_rule.json:
--------------------------------------------------------------------------------
1 | {
2 | "0": "其他垃圾/一次性快餐盒",
3 | "1": "其他垃圾/污损塑料",
4 | "2": "其他垃圾/烟蒂",
5 | "3": "其他垃圾/牙签",
6 | "4": "其他垃圾/破碎花盆及碟碗",
7 | "5": "其他垃圾/竹筷",
8 | "6": "厨余垃圾/剩饭剩菜",
9 | "7": "厨余垃圾/大骨头",
10 | "8": "厨余垃圾/水果果皮",
11 | "9": "厨余垃圾/水果果肉",
12 | "10": "厨余垃圾/茶叶渣",
13 | "11": "厨余垃圾/菜叶菜根",
14 | "12": "厨余垃圾/蛋壳",
15 | "13": "厨余垃圾/鱼骨",
16 | "14": "可回收物/充电宝",
17 | "15": "可回收物/包",
18 | "16": "可回收物/化妆品瓶",
19 | "17": "可回收物/塑料玩具",
20 | "18": "可回收物/塑料碗盆",
21 | "19": "可回收物/塑料衣架",
22 | "20": "可回收物/快递纸袋",
23 | "21": "可回收物/插头电线",
24 | "22": "可回收物/旧衣服",
25 | "23": "可回收物/易拉罐",
26 | "24": "可回收物/枕头",
27 | "25": "可回收物/毛绒玩具",
28 | "26": "可回收物/洗发水瓶",
29 | "27": "可回收物/玻璃杯",
30 | "28": "可回收物/皮鞋",
31 | "29": "可回收物/砧板",
32 | "30": "可回收物/纸板箱",
33 | "31": "可回收物/调料瓶",
34 | "32": "可回收物/酒瓶",
35 | "33": "可回收物/金属食品罐",
36 | "34": "可回收物/锅",
37 | "35": "可回收物/食用油桶",
38 | "36": "可回收物/饮料瓶",
39 | "37": "有害垃圾/干电池",
40 | "38": "有害垃圾/软膏",
41 | "39": "有害垃圾/过期药物"
42 | }
--------------------------------------------------------------------------------
/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/models/__init__.py
--------------------------------------------------------------------------------
/models/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/models/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/models/__pycache__/model.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/models/__pycache__/model.cpython-36.pyc
--------------------------------------------------------------------------------
/models/__pycache__/resnet50.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/models/__pycache__/resnet50.cpython-36.pyc
--------------------------------------------------------------------------------
/models/model.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: UTF-8 -*-
3 | # __author__: Qmh
4 | # __file_name__: models.py
5 | # __time__: 2019:06:27:19:51
6 |
7 | import keras.backend as K
8 | from keras.layers import Input
9 | from keras.layers.normalization import BatchNormalization
10 | from keras.layers import Conv2D, MaxPool2D, Dropout, Activation
11 | from keras.layers import Dense, Lambda, Add, GlobalAveragePooling2D, ZeroPadding2D, Multiply
12 | from keras.regularizers import l2
13 | from keras import Model
14 | from keras.layers.core import Permute
15 | from keras import regularizers
16 | from keras.layers import Conv1D, MaxPool1D, LSTM, ZeroPadding2D
17 | from keras import initializers
18 | from keras.layers import GlobalMaxPool1D, Permute, MaxPooling2D
19 | from keras.layers import GRU, TimeDistributed, Flatten, LeakyReLU, ELU
20 |
21 | # MODEL
22 | WEIGHT_DECAY = 0.0001 # 0.00001
23 | REDUCTION_RATIO = 4
24 | BLOCK_NUM = 1
25 |
26 |
27 | # DROPOUT= 0.5
28 | # Resblcok
29 | def res_conv_block(x, filters, strides, name):
30 | filter1, filer2, filter3 = filters
31 | # block a
32 | x = Conv2D(filter1, (1, 1), strides=strides, kernel_initializer='he_normal',
33 | kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY), name=f'{name}_conva')(x)
34 | x = BatchNormalization(name=f'{name}_bna')(x)
35 | x = Activation('relu', name=f'{name}_relua')(x)
36 | # block b
37 | x = Conv2D(filer2, (3, 3), padding='same', kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY),
38 | name=f'{name}_convb')(x)
39 | x = BatchNormalization(name=f'{name}_bnb')(x)
40 | x = Activation('relu', name=f'{name}_relub')(x)
41 | # block c
42 | x = Conv2D(filter3, (1, 1), name=f'{name}_convc', kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY))(x)
43 | x = BatchNormalization(name=f'{name}_bnc')(x)
44 | # shortcut
45 | shortcut = Conv2D(filter3, (1, 1), strides=strides, name=f'{name}_shcut',
46 | kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY))(x)
47 | shortcut = BatchNormalization(name=f'{name}_stbn')(x)
48 | x = Add(name=f'{name}_add')([x, shortcut])
49 | x = Activation('relu', name=f'{name}_relu')(x)
50 | return x
51 |
52 |
53 | # ResNet
54 | def ResNet_50(input_shape):
55 | x_in = Input(input_shape, name='input')
56 |
57 | x = Conv2D(64, (7, 7), strides=(2, 2), padding='same', name='conv1',
58 | kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY))(x_in)
59 | x = BatchNormalization(name="bn1")(x)
60 | x = Activation('relu')(x)
61 | x = MaxPool2D((3, 3), strides=(2, 2), padding='same', name='pool1')(x)
62 |
63 | x = res_conv_block(x, (64, 64, 256), (1, 1), name='block1')
64 | x = res_conv_block(x, (64, 64, 256), (1, 1), name='block2')
65 | x = res_conv_block(x, (64, 64, 256), (1, 1), name='block3')
66 |
67 | x = res_conv_block(x, (128, 128, 512), (1, 1), name='block4')
68 | x = res_conv_block(x, (128, 128, 512), (1, 1), name='block5')
69 | x = res_conv_block(x, (128, 128, 512), (1, 1), name='block6')
70 | x = res_conv_block(x, (128, 128, 512), (2, 2), name='block7')
71 |
72 | x = Conv2D(512, (x.shape[1].value, 1), name='fc6')(x)
73 | x = BatchNormalization(name="bn_fc6")(x)
74 | x = Activation('relu', name='relu_fc6')(x)
75 | # avgpool
76 | # x = GlobalAveragePooling2D(name='avgPool')(x)
77 | x = Lambda(lambda y: K.mean(y, axis=[1, 2]), name='avgpool')(x)
78 |
79 | model = Model(inputs=[x_in], outputs=[x], name='ResCNN')
80 | # model.summary()
81 | return model
82 |
83 |
84 | def squeeze_excitation(x, reduction_ratio, name):
85 | out_dim = int(x.shape[-1].value)
86 | x = GlobalAveragePooling2D(name=f'{name}_squeeze')(x)
87 | x = Dense(out_dim // reduction_ratio, activation='relu', name=f'{name}_ex0')(x)
88 | x = Dense(out_dim, activation='sigmoid', name=f'{name}_ex1')(x)
89 | return x
90 |
91 |
92 | def conv_block(x, filters, kernal_size, stride, name, stage, i, padding='same'):
93 | x = Conv2D(filters, kernal_size, strides=stride, padding=padding, name=f'{name}_conv{stage}_{i}',
94 | kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY))(x)
95 | x = BatchNormalization(name=f'{name}_bn{stage}_{i}')(x)
96 | if stage != 'c':
97 | # x = ELU(name=f'{name}_relu{stage}_{i}')(x)
98 | x = Activation('relu', name=f'{name}_relu{stage}_{i}')(x)
99 | return x
100 |
101 |
102 | def residual_block(x, outdim, stride, name):
103 | input_dim = int(x.shape[-1].value)
104 | shortcut = Conv2D(outdim, kernel_size=(1, 1), strides=stride, name=f'{name}_scut_conv',
105 | kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY))(x)
106 | shortcut = BatchNormalization(name=f'{name}_scut_norm')(shortcut)
107 |
108 | for i in range(BLOCK_NUM):
109 | if i > 0:
110 | stride = 1
111 | # x = Dropout(DROPOUT,name=f'{name}_drop{i-1}')(x)
112 | x = conv_block(x, outdim // 4, (1, 1), stride, name, 'a', i, padding='valid')
113 | x = conv_block(x, outdim // 4, (3, 3), (1, 1), name, 'b', i, padding='same')
114 | x = conv_block(x, outdim, (1, 1), (1, 1), name, 'c', i, padding='valid')
115 | # add SE
116 | x = Multiply(name=f'{name}_scale')([x, squeeze_excitation(x, REDUCTION_RATIO, name)])
117 | x = Add(name=f'{name}_scut')([shortcut, x])
118 | x = Activation('relu', name=f'{name}_relu')(x)
119 | return x
120 |
121 |
122 | # proposed model v4.0 timit libri
123 | def SE_ResNet(input_shape):
124 | # first layer
125 | x_in = Input(input_shape, name='input')
126 |
127 | x = ZeroPadding2D(padding=(3, 3), name='conv1_pad')(x_in)
128 | x = Conv2D(64, (7, 7),
129 | strides=(2, 2),
130 | padding='valid',
131 | kernel_initializer='he_normal',
132 | kernel_regularizer=regularizers.l2(WEIGHT_DECAY),
133 | name='conv1')(x)
134 | x = BatchNormalization(name='bn_conv1')(x)
135 | x = Activation('relu', name='relu1')(x)
136 | # x = ELU(name=f'relu1')(x)
137 | x = ZeroPadding2D(padding=(1, 1), name='pool1_pad')(x)
138 | x = MaxPooling2D((3, 3), strides=(2, 2))(x)
139 |
140 | x = residual_block(x, outdim=256, stride=(2, 2), name='block1')
141 | x = residual_block(x, outdim=256, stride=(2, 2), name='block2')
142 | x = residual_block(x, outdim=256, stride=(2, 2), name='block3')
143 | # x = residual_block(x,outdim=256,stride=(2,2),name='block4')
144 |
145 | x = residual_block(x, outdim=512, stride=(2, 2), name='block5')
146 | x = residual_block(x, outdim=512, stride=(2, 2), name='block6')
147 | # x = residual_block(x,outdim=512,stride=(2,2),name='block7')
148 |
149 | x = Flatten(name='flatten')(x)
150 |
151 | x = Dropout(0.5, name='drop1')(x)
152 | x = Dense(512, kernel_regularizer=regularizers.l2(WEIGHT_DECAY), name='fc1')(x)
153 | x = BatchNormalization(name='bn_fc1')(x)
154 | # x = ELU(name=f'relu_fc1')(x)
155 | x = Activation('relu', name=f'relu_fc1')(x)
156 |
157 | return Model(inputs=[x_in], outputs=[x], name='SEResNet')
158 |
159 |
160 | # vggvox1
161 | def conv_pool(x, layerid, filters, kernal_size, conv_strides, pool_size=None, pool_strides=None, pool=None):
162 | x = Conv2D(filters, kernal_size, strides=conv_strides, padding='same', name=f'conv{layerid}')(x)
163 | x = BatchNormalization(name=f'bn{layerid}')(x)
164 | x = Activation('relu', name=f'relu{layerid}')(x)
165 | if pool == 'max':
166 | x = MaxPool2D(pool_size, pool_strides, name=f'mpool{layerid}')(x)
167 | return x
168 |
169 |
170 | def vggvox1_cnn(input_shape):
171 | x_in = Input(input_shape, name='input')
172 | x = conv_pool(x_in, 1, 96, (7, 7), (2, 2), (3, 3), (2, 2), 'max')
173 | x = conv_pool(x, 2, 256, (5, 5), (2, 2), (3, 3), (2, 2), 'max')
174 | x = conv_pool(x, 3, 384, (3, 3), (1, 1))
175 | x = conv_pool(x, 4, 256, (3, 3), (1, 1))
176 | x = conv_pool(x, 5, 256, (3, 3), (1, 1), (5, 3), (3, 2), 'max')
177 | # fc 6
178 | x = Conv2D(256, (9, 1), name='fc6')(x)
179 | # apool6
180 | x = GlobalAveragePooling2D(name='avgPool')(x)
181 | # fc7
182 | x = Dense(512, name='fc7', activation='relu')(x)
183 | model = Model(inputs=[x_in], outputs=[x], name='vggvox1_cnn')
184 | return model
185 |
186 |
187 | # def vggvox1_cnn(input_shape):
188 | # x_in = Input(input_shape,name='input')
189 | # x = conv_pool(x_in,1,96,(7,7),(1,1),(3,3),(2,2),'max')
190 | # x = conv_pool(x,2,256,(5,5),(1,1),(3,3),(2,2),'max')
191 | # x = conv_pool(x,3,384,(3,3),(1,1))
192 | # x = conv_pool(x,4,256,(3,3),(1,1))
193 | # x = conv_pool(x,5,256,(3,3),(1,1),(5,3),(2,2),'max')
194 | # # fc 6
195 | # x = Conv2D(256,(x.shape[1].value,1),name='fc6')(x)
196 | # # apool6
197 | # x = GlobalAveragePooling2D(name='avgPool')(x)
198 | # # fc7
199 | # x = Dense(512,name='fc7',activation='relu')(x)
200 | # model = Model(inputs=[x_in],outputs=[x],name='vggvox1_cnn')
201 | # return model
202 |
203 | # deep speaker
204 | def clipped_relu(inputs):
205 | return Lambda(lambda y: K.minimum(K.maximum(y, 0), 20))(inputs)
206 |
207 |
208 | def identity_block(x_in, kernel_size, filters, name):
209 | x = Conv2D(filters, kernel_size=kernel_size, strides=(1, 1),
210 | padding='same', kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY),
211 | name=f'{name}_conva')(x_in)
212 | x = BatchNormalization(name=f'{name}_bn1')(x)
213 | x = clipped_relu(x)
214 | x = Conv2D(filters, kernel_size=kernel_size, strides=(1, 1),
215 | padding='same', kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY),
216 | name=f'{name}_convb')(x)
217 | x = BatchNormalization(name=f'{name}_bn2')(x)
218 | x = Add(name=f'{name}_add')([x, x_in])
219 | x = clipped_relu(x)
220 | return x
221 |
222 |
223 | def Deep_speaker_model(input_shape):
224 | def conv_and_res_block(x_in, filters):
225 | x = Conv2D(filters, kernel_size=(5, 5), strides=(2, 2),
226 | padding='same', kernel_regularizer=regularizers.l2(l=WEIGHT_DECAY),
227 | name=f'conv_{filters}-s')(x_in)
228 | x = BatchNormalization(name=f'conv_{filters}-s_bn')(x)
229 | x = clipped_relu(x)
230 | for i in range(3):
231 | x = identity_block(x, kernel_size=(3, 3), filters=filters, name=f'res{filters}_{i}')
232 | return x
233 |
234 | x_in = Input(input_shape, name='input')
235 | x = Permute((2, 1, 3), name='permute')(x_in)
236 | x = conv_and_res_block(x, 64)
237 | x = conv_and_res_block(x, 128)
238 | x = conv_and_res_block(x, 256)
239 | x = conv_and_res_block(x, 512)
240 | # average
241 | x = Lambda(lambda y: K.mean(y, axis=[1, 2]), name='avgpool')(x)
242 | # affine
243 | x = Dense(512, name='affine')(x)
244 | x = Lambda(lambda y: K.l2_normalize(y, axis=1), name='ln')(x)
245 | model = Model(inputs=[x_in], outputs=[x], name='deepspeaker')
246 | return model
247 |
248 |
249 | # proposed model
250 | def Baseline_GRU(input_shape):
251 | # first layer
252 | x_in = Input(input_shape, name='input')
253 | x = Conv2D(64, (3, 3), strides=(1, 1), padding='same', name='conv1')(x_in)
254 | x = BatchNormalization(name='bn1')(x)
255 | x = ELU(name='relu1')(x)
256 | x = MaxPool2D((2, 2), strides=(2, 2), padding='same', name='pool1')(x)
257 |
258 | x = Conv2D(64, (3, 3), strides=(1, 1), padding='same', name='conv2')(x)
259 | x = BatchNormalization(name='bn2')(x)
260 | x = ELU(name='relu2')(x)
261 | x = MaxPool2D((2, 2), strides=(2, 2), padding='same', name='pool2')(x)
262 |
263 | x = TimeDistributed(Flatten(), name='timedis1')(x)
264 | x = GRU(512, return_sequences=True, name='gru1')(x)
265 | x = GRU(512, return_sequences=True, name='gru2')(x)
266 | x = GRU(512, return_sequences=False, name='gru4')(x)
267 |
268 | x = Dense(512, name='fc2', activation='relu')(x)
269 | x = BatchNormalization(name='fc_norm')(x)
270 | x = ELU(name='relu3')(x)
271 |
272 | return Model(inputs=[x_in], outputs=[x], name='Baseline_GRU')
273 |
274 |
275 | if __name__ == "__main__":
276 | # model = ResNet(c.INPUT_SHPE)
277 | model = vggvox1_cnn((299, 40, 1))
278 | # model = Deep_speaker_model(c.INPUT_SHPE)
279 | # # model = SE_ResNet(c.INPUT_SHPE)
280 | # model = RWCNN_LSTM((59049,1))
281 | print(model.summary())
282 |
--------------------------------------------------------------------------------
/models/resnet50.py:
--------------------------------------------------------------------------------
1 | """Enables dynamic setting of underlying Keras module.
2 | """
3 | from __future__ import absolute_import
4 | from __future__ import division
5 | from __future__ import print_function
6 |
7 | import os
8 | import json
9 | import warnings
10 | import numpy as np
11 |
12 | from keras.applications import backend
13 | from keras.applications import layers
14 | from keras.applications import models
15 | from keras.applications import utils
16 |
17 | _KERAS_BACKEND = backend
18 | _KERAS_LAYERS = layers
19 | _KERAS_MODELS = models
20 | _KERAS_UTILS = utils
21 |
22 | CLASS_INDEX = None
23 | CLASS_INDEX_PATH = ('https://modelarts-competitions.obs.cn-north-1.myhuaweicloud.com/'
24 | 'model_zoo/resnet/imagenet_class_index.json')
25 |
26 | # Global tensor of imagenet mean for preprocessing symbolic inputs
27 | _IMAGENET_MEAN = None
28 |
29 | WEIGHTS_PATH = ('https://github.com/fchollet/deep-learning-models/'
30 | 'releases/download/v0.2/'
31 | 'resnet50_weights_tf_dim_ordering_tf_kernels.h5')
32 | WEIGHTS_PATH_NO_TOP = ('https://modelarts-competitions.obs.cn-north-1.myhuaweicloud.com/'
33 | 'model_zoo/resnet/'
34 | 'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')
35 |
36 |
37 | def get_submodules_from_kwargs(kwargs):
38 | backend = kwargs.get('backend', _KERAS_BACKEND)
39 | layers = kwargs.get('layers', _KERAS_LAYERS)
40 | models = kwargs.get('models', _KERAS_MODELS)
41 | utils = kwargs.get('utils', _KERAS_UTILS)
42 | for key in kwargs.keys():
43 | if key not in ['backend', 'layers', 'models', 'utils']:
44 | raise TypeError('Invalid keyword argument: %s', key)
45 | return backend, layers, models, utils
46 |
47 |
48 | def correct_pad(backend, inputs, kernel_size):
49 | """Returns a tuple for zero-padding for 2D convolution with downsampling.
50 |
51 | # Arguments
52 | input_size: An integer or tuple/list of 2 integers.
53 | kernel_size: An integer or tuple/list of 2 integers.
54 |
55 | # Returns
56 | A tuple.
57 | """
58 | img_dim = 2 if backend.image_data_format() == 'channels_first' else 1
59 | input_size = backend.int_shape(inputs)[img_dim:(img_dim + 2)]
60 |
61 | if isinstance(kernel_size, int):
62 | kernel_size = (kernel_size, kernel_size)
63 |
64 | if input_size[0] is None:
65 | adjust = (1, 1)
66 | else:
67 | adjust = (1 - input_size[0] % 2, 1 - input_size[1] % 2)
68 |
69 | correct = (kernel_size[0] // 2, kernel_size[1] // 2)
70 |
71 | return ((correct[0] - adjust[0], correct[0]),
72 | (correct[1] - adjust[1], correct[1]))
73 |
74 |
75 | __version__ = '1.0.7'
76 |
77 |
78 | def _preprocess_numpy_input(x, data_format, mode, **kwargs):
79 | """Preprocesses a Numpy array encoding a batch of images.
80 |
81 | # Arguments
82 | x: Input array, 3D or 4D.
83 | data_format: Data format of the image array.
84 | mode: One of "caffe", "tf" or "torch".
85 | - caffe: will convert the images from RGB to BGR,
86 | then will zero-center each color channel with
87 | respect to the ImageNet dataset,
88 | without scaling.
89 | - tf: will scale pixels between -1 and 1,
90 | sample-wise.
91 | - torch: will scale pixels between 0 and 1 and then
92 | will normalize each channel with respect to the
93 | ImageNet dataset.
94 |
95 | # Returns
96 | Preprocessed Numpy array.
97 | """
98 | backend, _, _, _ = get_submodules_from_kwargs(kwargs)
99 | if not issubclass(x.dtype.type, np.floating):
100 | x = x.astype(backend.floatx(), copy=False)
101 |
102 | if mode == 'tf':
103 | x /= 127.5
104 | x -= 1.
105 |
106 | return x
107 |
108 | if mode == 'torch':
109 | x /= 255.
110 | mean = [0.485, 0.456, 0.406]
111 | std = [0.229, 0.224, 0.225]
112 | else:
113 | if data_format == 'channels_first':
114 | # 'RGB'->'BGR'
115 | if x.ndim == 3:
116 | x = x[::-1, ...]
117 | else:
118 | x = x[:, ::-1, ...]
119 | else:
120 | # 'RGB'->'BGR'
121 | x = x[..., ::-1]
122 | mean = [103.939, 116.779, 123.68]
123 | std = None
124 |
125 | # Zero-center by mean pixel
126 | if data_format == 'channels_first':
127 | if x.ndim == 3:
128 | x[0, :, :] -= mean[0]
129 | x[1, :, :] -= mean[1]
130 | x[2, :, :] -= mean[2]
131 | if std is not None:
132 | x[0, :, :] /= std[0]
133 | x[1, :, :] /= std[1]
134 | x[2, :, :] /= std[2]
135 | else:
136 | x[:, 0, :, :] -= mean[0]
137 | x[:, 1, :, :] -= mean[1]
138 | x[:, 2, :, :] -= mean[2]
139 | if std is not None:
140 | x[:, 0, :, :] /= std[0]
141 | x[:, 1, :, :] /= std[1]
142 | x[:, 2, :, :] /= std[2]
143 | else:
144 | x[..., 0] -= mean[0]
145 | x[..., 1] -= mean[1]
146 | x[..., 2] -= mean[2]
147 | if std is not None:
148 | x[..., 0] /= std[0]
149 | x[..., 1] /= std[1]
150 | x[..., 2] /= std[2]
151 | return x
152 |
153 |
154 | def _preprocess_symbolic_input(x, data_format, mode, **kwargs):
155 | """Preprocesses a tensor encoding a batch of images.
156 |
157 | # Arguments
158 | x: Input tensor, 3D or 4D.
159 | data_format: Data format of the image tensor.
160 | mode: One of "caffe", "tf" or "torch".
161 | - caffe: will convert the images from RGB to BGR,
162 | then will zero-center each color channel with
163 | respect to the ImageNet dataset,
164 | without scaling.
165 | - tf: will scale pixels between -1 and 1,
166 | sample-wise.
167 | - torch: will scale pixels between 0 and 1 and then
168 | will normalize each channel with respect to the
169 | ImageNet dataset.
170 |
171 | # Returns
172 | Preprocessed tensor.
173 | """
174 | global _IMAGENET_MEAN
175 |
176 | backend, _, _, _ = get_submodules_from_kwargs(kwargs)
177 |
178 | if mode == 'tf':
179 | x /= 127.5
180 | x -= 1.
181 | return x
182 |
183 | if mode == 'torch':
184 | x /= 255.
185 | mean = [0.485, 0.456, 0.406]
186 | std = [0.229, 0.224, 0.225]
187 | else:
188 | if data_format == 'channels_first':
189 | # 'RGB'->'BGR'
190 | if backend.ndim(x) == 3:
191 | x = x[::-1, ...]
192 | else:
193 | x = x[:, ::-1, ...]
194 | else:
195 | # 'RGB'->'BGR'
196 | x = x[..., ::-1]
197 | mean = [103.939, 116.779, 123.68]
198 | std = None
199 |
200 | if _IMAGENET_MEAN is None:
201 | _IMAGENET_MEAN = backend.constant(-np.array(mean))
202 |
203 | # Zero-center by mean pixel
204 | if backend.dtype(x) != backend.dtype(_IMAGENET_MEAN):
205 | x = backend.bias_add(
206 | x, backend.cast(_IMAGENET_MEAN, backend.dtype(x)),
207 | data_format=data_format)
208 | else:
209 | x = backend.bias_add(x, _IMAGENET_MEAN, data_format)
210 | if std is not None:
211 | x /= std
212 | return x
213 |
214 |
215 | def preprocess_input(x, data_format=None, mode='caffe', **kwargs):
216 | """Preprocesses a tensor or Numpy array encoding a batch of images.
217 |
218 | # Arguments
219 | x: Input Numpy or symbolic tensor, 3D or 4D.
220 | The preprocessed data is written over the input data
221 | if the data types are compatible. To avoid this
222 | behaviour, `numpy.copy(x)` can be used.
223 | data_format: Data format of the image tensor/array.
224 | mode: One of "caffe", "tf" or "torch".
225 | - caffe: will convert the images from RGB to BGR,
226 | then will zero-center each color channel with
227 | respect to the ImageNet dataset,
228 | without scaling.
229 | - tf: will scale pixels between -1 and 1,
230 | sample-wise.
231 | - torch: will scale pixels between 0 and 1 and then
232 | will normalize each channel with respect to the
233 | ImageNet dataset.
234 |
235 | # Returns
236 | Preprocessed tensor or Numpy array.
237 |
238 | # Raises
239 | ValueError: In case of unknown `data_format` argument.
240 | """
241 | backend, _, _, _ = get_submodules_from_kwargs(kwargs)
242 |
243 | if data_format is None:
244 | data_format = backend.image_data_format()
245 | if data_format not in {'channels_first', 'channels_last'}:
246 | raise ValueError('Unknown data_format ' + str(data_format))
247 |
248 | if isinstance(x, np.ndarray):
249 | return _preprocess_numpy_input(x, data_format=data_format,
250 | mode=mode, **kwargs)
251 | else:
252 | return _preprocess_symbolic_input(x, data_format=data_format,
253 | mode=mode, **kwargs)
254 |
255 |
256 | def decode_predictions(preds, top=5, **kwargs):
257 | """Decodes the prediction of an ImageNet model.
258 |
259 | # Arguments
260 | preds: Numpy tensor encoding a batch of predictions.
261 | top: Integer, how many top-guesses to return.
262 |
263 | # Returns
264 | A list of lists of top class prediction tuples
265 | `(class_name, class_description, score)`.
266 | One list of tuples per sample in batch input.
267 |
268 | # Raises
269 | ValueError: In case of invalid shape of the `pred` array
270 | (must be 2D).
271 | """
272 | global CLASS_INDEX
273 |
274 | backend, _, _, keras_utils = get_submodules_from_kwargs(kwargs)
275 |
276 | if len(preds.shape) != 2 or preds.shape[1] != 1000:
277 | raise ValueError('`decode_predictions` expects '
278 | 'a batch of predictions '
279 | '(i.e. a 2D array of shape (samples, 1000)). '
280 | 'Found array with shape: ' + str(preds.shape))
281 | if CLASS_INDEX is None:
282 | fpath = keras_utils.get_file(
283 | 'imagenet_class_index.json',
284 | CLASS_INDEX_PATH,
285 | cache_subdir='models',
286 | file_hash='c2c37ea517e94d9795004a39431a14cb',
287 | cache_dir=os.path.join(os.path.dirname(__file__), '..'))
288 | with open(fpath) as f:
289 | CLASS_INDEX = json.load(f)
290 | results = []
291 | for pred in preds:
292 | top_indices = pred.argsort()[-top:][::-1]
293 | result = [tuple(CLASS_INDEX[str(i)]) + (pred[i],) for i in top_indices]
294 | result.sort(key=lambda x: x[2], reverse=True)
295 | results.append(result)
296 | return results
297 |
298 |
299 | def _obtain_input_shape(input_shape,
300 | default_size,
301 | min_size,
302 | data_format,
303 | require_flatten,
304 | weights=None):
305 | """Internal utility to compute/validate a model's input shape.
306 |
307 | # Arguments
308 | input_shape: Either None (will return the default network input shape),
309 | or a user-provided shape to be validated.
310 | default_size: Default input width/height for the model.
311 | min_size: Minimum input width/height accepted by the model.
312 | data_format: Image data format to use.
313 | require_flatten: Whether the model is expected to
314 | be linked to a classifier via a Flatten layer.
315 | weights: One of `None` (random initialization)
316 | or 'imagenet' (pre-training on ImageNet).
317 | If weights='imagenet' input channels must be equal to 3.
318 |
319 | # Returns
320 | An integer shape tuple (may include None entries).
321 |
322 | # Raises
323 | ValueError: In case of invalid argument values.
324 | """
325 | if weights != 'imagenet' and input_shape and len(input_shape) == 3:
326 | if data_format == 'channels_first':
327 | if input_shape[0] not in {1, 3}:
328 | warnings.warn(
329 | 'This model usually expects 1 or 3 input channels. '
330 | 'However, it was passed an input_shape with ' +
331 | str(input_shape[0]) + ' input channels.')
332 | default_shape = (input_shape[0], default_size, default_size)
333 | else:
334 | if input_shape[-1] not in {1, 3}:
335 | warnings.warn(
336 | 'This model usually expects 1 or 3 input channels. '
337 | 'However, it was passed an input_shape with ' +
338 | str(input_shape[-1]) + ' input channels.')
339 | default_shape = (default_size, default_size, input_shape[-1])
340 | else:
341 | if data_format == 'channels_first':
342 | default_shape = (3, default_size, default_size)
343 | else:
344 | default_shape = (default_size, default_size, 3)
345 | if weights == 'imagenet' and require_flatten:
346 | if input_shape is not None:
347 | if input_shape != default_shape:
348 | raise ValueError('When setting `include_top=True` '
349 | 'and loading `imagenet` weights, '
350 | '`input_shape` should be ' +
351 | str(default_shape) + '.')
352 | return default_shape
353 | if input_shape:
354 | if data_format == 'channels_first':
355 | if input_shape is not None:
356 | if len(input_shape) != 3:
357 | raise ValueError(
358 | '`input_shape` must be a tuple of three integers.')
359 | if input_shape[0] != 3 and weights == 'imagenet':
360 | raise ValueError('The input must have 3 channels; got '
361 | '`input_shape=' + str(input_shape) + '`')
362 | if ((input_shape[1] is not None and input_shape[1] < min_size) or
363 | (input_shape[2] is not None and input_shape[2] < min_size)):
364 | raise ValueError('Input size must be at least ' +
365 | str(min_size) + 'x' + str(min_size) +
366 | '; got `input_shape=' +
367 | str(input_shape) + '`')
368 | else:
369 | if input_shape is not None:
370 | if len(input_shape) != 3:
371 | raise ValueError(
372 | '`input_shape` must be a tuple of three integers.')
373 | if input_shape[-1] != 3 and weights == 'imagenet':
374 | raise ValueError('The input must have 3 channels; got '
375 | '`input_shape=' + str(input_shape) + '`')
376 | if ((input_shape[0] is not None and input_shape[0] < min_size) or
377 | (input_shape[1] is not None and input_shape[1] < min_size)):
378 | raise ValueError('Input size must be at least ' +
379 | str(min_size) + 'x' + str(min_size) +
380 | '; got `input_shape=' +
381 | str(input_shape) + '`')
382 | else:
383 | if require_flatten:
384 | input_shape = default_shape
385 | else:
386 | if data_format == 'channels_first':
387 | input_shape = (3, None, None)
388 | else:
389 | input_shape = (None, None, 3)
390 | if require_flatten:
391 | if None in input_shape:
392 | raise ValueError('If `include_top` is True, '
393 | 'you should specify a static `input_shape`. '
394 | 'Got `input_shape=' + str(input_shape) + '`')
395 | return input_shape
396 |
397 |
398 | backend = None
399 | layers = None
400 | models = None
401 | keras_utils = None
402 |
403 |
404 | def identity_block(input_tensor, kernel_size, filters, stage, block):
405 | """The identity block is the block that has no conv layer at shortcut.
406 |
407 | # Arguments
408 | input_tensor: input tensor
409 | kernel_size: default 3, the kernel size of
410 | middle conv layer at main path
411 | filters: list of integers, the filters of 3 conv layer at main path
412 | stage: integer, current stage label, used for generating layer names
413 | block: 'a','b'..., current block label, used for generating layer names
414 |
415 | # Returns
416 | Output tensor for the block.
417 | """
418 | filters1, filters2, filters3 = filters
419 | if backend.image_data_format() == 'channels_last':
420 | bn_axis = 3
421 | else:
422 | bn_axis = 1
423 | conv_name_base = 'res' + str(stage) + block + '_branch'
424 | bn_name_base = 'bn' + str(stage) + block + '_branch'
425 |
426 | x = layers.Conv2D(filters1, (1, 1),
427 | kernel_initializer='he_normal',
428 | name=conv_name_base + '2a')(input_tensor)
429 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
430 | x = layers.Activation('relu')(x)
431 |
432 | x = layers.Conv2D(filters2, kernel_size,
433 | padding='same',
434 | kernel_initializer='he_normal',
435 | name=conv_name_base + '2b')(x)
436 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
437 | x = layers.Activation('relu')(x)
438 |
439 | x = layers.Conv2D(filters3, (1, 1),
440 | kernel_initializer='he_normal',
441 | name=conv_name_base + '2c')(x)
442 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
443 |
444 | x = layers.add([x, input_tensor])
445 | x = layers.Activation('relu')(x)
446 | return x
447 |
448 |
449 | def conv_block(input_tensor,
450 | kernel_size,
451 | filters,
452 | stage,
453 | block,
454 | strides=(2, 2)):
455 | """A block that has a conv layer at shortcut.
456 |
457 | # Arguments
458 | input_tensor: input tensor
459 | kernel_size: default 3, the kernel size of
460 | middle conv layer at main path
461 | filters: list of integers, the filters of 3 conv layer at main path
462 | stage: integer, current stage label, used for generating layer names
463 | block: 'a','b'..., current block label, used for generating layer names
464 | strides: Strides for the first conv layer in the block.
465 |
466 | # Returns
467 | Output tensor for the block.
468 |
469 | Note that from stage 3,
470 | the first conv layer at main path is with strides=(2, 2)
471 | And the shortcut should have strides=(2, 2) as well
472 | """
473 | filters1, filters2, filters3 = filters
474 | if backend.image_data_format() == 'channels_last':
475 | bn_axis = 3
476 | else:
477 | bn_axis = 1
478 | conv_name_base = 'res' + str(stage) + block + '_branch'
479 | bn_name_base = 'bn' + str(stage) + block + '_branch'
480 |
481 | x = layers.Conv2D(filters1, (1, 1), strides=strides,
482 | kernel_initializer='he_normal',
483 | name=conv_name_base + '2a')(input_tensor)
484 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
485 | x = layers.Activation('relu')(x)
486 |
487 | x = layers.Conv2D(filters2, kernel_size, padding='same',
488 | kernel_initializer='he_normal',
489 | name=conv_name_base + '2b')(x)
490 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
491 | x = layers.Activation('relu')(x)
492 |
493 | x = layers.Conv2D(filters3, (1, 1),
494 | kernel_initializer='he_normal',
495 | name=conv_name_base + '2c')(x)
496 | x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
497 |
498 | shortcut = layers.Conv2D(filters3, (1, 1), strides=strides,
499 | kernel_initializer='he_normal',
500 | name=conv_name_base + '1')(input_tensor)
501 | shortcut = layers.BatchNormalization(
502 | axis=bn_axis, name=bn_name_base + '1')(shortcut)
503 |
504 | x = layers.add([x, shortcut])
505 | x = layers.Activation('relu')(x)
506 | return x
507 |
508 |
509 | def ResNet50(include_top=True,
510 | weights='imagenet',
511 | input_tensor=None,
512 | input_shape=None,
513 | pooling=None,
514 | classes=1000,
515 | **kwargs):
516 | """Instantiates the ResNet50 architecture.
517 |
518 | Optionally loads weights pre-trained on ImageNet.
519 | Note that the data format convention used by the model is
520 | the one specified in your Keras config at `~/.keras/keras.json`.
521 |
522 | # Arguments
523 | include_top: whether to include the fully-connected
524 | layer at the top of the network.
525 | weights: one of `None` (random initialization),
526 | 'imagenet' (pre-training on ImageNet),
527 | or the path to the weights file to be loaded.
528 | input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
529 | to use as image input for the model.
530 | input_shape: optional shape tuple, only to be specified
531 | if `include_top` is False (otherwise the input shape
532 | has to be `(224, 224, 3)` (with `channels_last` data format)
533 | or `(3, 224, 224)` (with `channels_first` data format).
534 | It should have exactly 3 inputs channels,
535 | and width and height should be no smaller than 32.
536 | E.g. `(200, 200, 3)` would be one valid value.
537 | pooling: Optional pooling mode for feature extraction
538 | when `include_top` is `False`.
539 | - `None` means that the output of the model will be
540 | the 4D tensor output of the
541 | last convolutional block.
542 | - `avg` means that global average pooling
543 | will be applied to the output of the
544 | last convolutional block, and thus
545 | the output of the model will be a 2D tensor.
546 | - `max` means that global max pooling will
547 | be applied.
548 | classes: optional number of classes to classify images
549 | into, only to be specified if `include_top` is True, and
550 | if no `weights` argument is specified.
551 |
552 | # Returns
553 | A Keras model instance.
554 |
555 | # Raises
556 | ValueError: in case of invalid argument for `weights`,
557 | or invalid input shape.
558 | """
559 | global backend, layers, models, keras_utils
560 | backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)
561 |
562 | if not (weights in {'imagenet', None} or os.path.exists(weights)):
563 | raise ValueError('The `weights` argument should be either '
564 | '`None` (random initialization), `imagenet` '
565 | '(pre-training on ImageNet), '
566 | 'or the path to the weights file to be loaded.')
567 |
568 | if weights == 'imagenet' and include_top and classes != 1000:
569 | raise ValueError('If using `weights` as `"imagenet"` with `include_top`'
570 | ' as true, `classes` should be 1000')
571 |
572 | # Determine proper input shape
573 | input_shape = _obtain_input_shape(input_shape,
574 | default_size=224,
575 | min_size=32,
576 | data_format=backend.image_data_format(),
577 | require_flatten=include_top,
578 | weights=weights)
579 |
580 | if input_tensor is None:
581 | img_input = layers.Input(shape=input_shape)
582 | else:
583 | if not backend.is_keras_tensor(input_tensor):
584 | img_input = layers.Input(tensor=input_tensor, shape=input_shape)
585 | else:
586 | img_input = input_tensor
587 | if backend.image_data_format() == 'channels_last':
588 | bn_axis = 3
589 | else:
590 | bn_axis = 1
591 |
592 | x = layers.ZeroPadding2D(padding=(3, 3), name='conv1_pad')(img_input)
593 | x = layers.Conv2D(64, (7, 7),
594 | strides=(2, 2),
595 | padding='valid',
596 | kernel_initializer='he_normal',
597 | name='conv1')(x)
598 | x = layers.BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
599 | x = layers.Activation('relu')(x)
600 | x = layers.ZeroPadding2D(padding=(1, 1), name='pool1_pad')(x)
601 | x = layers.MaxPooling2D((3, 3), strides=(2, 2))(x)
602 |
603 | x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
604 | x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
605 | x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')
606 |
607 | x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
608 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
609 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
610 | x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')
611 |
612 | x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
613 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
614 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
615 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
616 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
617 | x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')
618 |
619 | x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
620 | x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
621 | x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
622 |
623 | if include_top:
624 | x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
625 | x = layers.Dense(classes, activation='softmax', name='fc1000')(x)
626 | else:
627 | if pooling == 'avg':
628 | x = layers.GlobalAveragePooling2D()(x)
629 | elif pooling == 'max':
630 | x = layers.GlobalMaxPooling2D()(x)
631 | else:
632 | warnings.warn('The output shape of `ResNet50(include_top=False)` '
633 | 'has been changed since Keras 2.2.0.')
634 |
635 | # Ensure that the model takes into account
636 | # any potential predecessors of `input_tensor`.
637 | if input_tensor is not None:
638 | inputs = keras_utils.get_source_inputs(input_tensor)
639 | else:
640 | inputs = img_input
641 | # Create model.
642 | model = models.Model(inputs, x, name='resnet50')
643 |
644 | # Load weights.
645 | if weights == 'imagenet':
646 | if include_top:
647 | weights_path = keras_utils.get_file(
648 | 'resnet50_weights_tf_dim_ordering_tf_kernels.h5',
649 | WEIGHTS_PATH,
650 | cache_subdir='models',
651 | md5_hash='a7b3fe01876f51b976af0dea6bc144eb',
652 | cache_dir=os.path.join(os.path.dirname(__file__), '..'))
653 | else:
654 | weights_path = keras_utils.get_file(
655 | 'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',
656 | WEIGHTS_PATH_NO_TOP,
657 | cache_subdir='models',
658 | md5_hash='a268eb855778b3df3c7506639542a6af',
659 | cache_dir=os.path.join(os.path.dirname(__file__), '..'))
660 | model.load_weights(weights_path)
661 | if backend.backend() == 'theano':
662 | keras_utils.convert_all_kernels_in_model(model)
663 | elif weights is not None:
664 | model.load_weights(weights)
665 |
666 | return model
667 |
--------------------------------------------------------------------------------
/models/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/models/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5
--------------------------------------------------------------------------------
/prediction.py:
--------------------------------------------------------------------------------
1 | import tensorflow as tf
2 | import re
3 | import json
4 | from data_process import preprocess_img, preprocess_img_from_Url
5 | from models.resnet50 import ResNet50
6 | from keras.layers import Dense, Dropout, BatchNormalization, GlobalAveragePooling2D
7 | from keras.models import Model
8 | import numpy as np
9 | from keras import regularizers
10 | from tensorflow.python.keras.backend import set_session
11 |
12 | config = tf.ConfigProto()
13 | config.gpu_options.allow_growth = True
14 | config.gpu_options.per_process_gpu_memory_fraction = 0.7
15 | sess = tf.Session(config=config)
16 |
17 | # 全局配置文件
18 | tf.app.flags.DEFINE_integer('num_classes', 40, '垃圾分类数目')
19 | tf.app.flags.DEFINE_integer('input_size', 224, '模型输入图片大小')
20 | tf.app.flags.DEFINE_integer('batch_size', 16, '图片批处理大小')
21 |
22 | FLAGS = tf.app.flags.FLAGS
23 | h5_weights_path = './output_model/best.h5'
24 |
25 |
26 | ## 增加最后输出层
27 | def add_new_last_layer(base_model, num_classes):
28 | x = base_model.output
29 | x = GlobalAveragePooling2D(name='avg_pool')(x)
30 | x = Dropout(0.5, name='dropout1')(x)
31 | # x = Dense(1024,activation='relu',kernel_regularizer= regularizers.l2(0.0001),name='fc1')(x)
32 | # x = BatchNormalization(name='bn_fc_00')(x)
33 | x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.0001), name='fc2')(x)
34 | x = BatchNormalization(name='bn_fc_01')(x)
35 | x = Dropout(0.5, name='dropout2')(x)
36 | x = Dense(num_classes, activation='softmax')(x)
37 | model = Model(inputs=base_model.input, outputs=x)
38 | return model
39 |
40 |
41 | # 加载模型
42 | def model_fn(FLAGS):
43 | # K.set_learning_phase(0)
44 | # setup model
45 | base_model = ResNet50(weights="imagenet",
46 | include_top=False,
47 | pooling=None,
48 | input_shape=(FLAGS.input_size, FLAGS.input_size, 3),
49 | classes=FLAGS.num_classes)
50 | for layer in base_model.layers:
51 | layer.trainable = False
52 |
53 | # if FLAGS.mode == 'train':
54 | # K.set_learning_phase(1)
55 | model = add_new_last_layer(base_model, FLAGS.num_classes)
56 |
57 | # print(model.summary())
58 | # print(model.layers[84].name)
59 | # exit()
60 |
61 | # Adam = adam(lr=FLAGS.learning_rate,clipnorm=0.001)
62 | model.compile(optimizer="adam", loss='categorical_crossentropy', metrics=['accuracy'])
63 | return model
64 |
65 |
66 | # 加载封装测试模型
67 | def init_artificial_neural_network(sess):
68 | set_session(sess)
69 | model = model_fn(FLAGS)
70 | model.load_weights(h5_weights_path, by_name=True)
71 | return model
72 |
73 |
74 | ## 测试图片
75 | def prediction_result_from_img(model, imgurl):
76 | # 加载分类数据
77 | try:
78 | with open("./garbage_classify/garbage_classify_rule.json", 'rb') as load_f:
79 | load_dict = json.load(load_f)
80 | if re.match(r'^https?:/{2}\w.+$', imgurl):
81 | test_data = preprocess_img_from_Url(imgurl, FLAGS.input_size)
82 | else:
83 | test_data = preprocess_img(imgurl, FLAGS.input_size)
84 |
85 | if test_data != 0:
86 | tta_num = 5
87 | predictions = [0 * tta_num]
88 | for i in range(tta_num):
89 | x_test = test_data[i]
90 | x_test = x_test[np.newaxis, :, :, :]
91 | prediction = model.predict(x_test)[0]
92 | # print(prediction)
93 | predictions += prediction
94 | pred_label = np.argmax(predictions, axis=0)
95 | print('-------深度学习垃圾分类预测结果----------')
96 | print(pred_label)
97 | print(load_dict[str(pred_label)])
98 | print('-------深度学习垃圾分类预测结果--------')
99 | return load_dict[str(pred_label)]
100 | else:
101 | print('-------文件读取错误----------')
102 | return False
103 | except Exception as e:
104 | print('发生了异常-prediction:', e)
105 |
106 | # if __name__ == "__main__":
107 |
108 | # test_img('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1572815106329&di=bf107149c926f3114c25e74ef3b79275&imgtype=0&src=http%3A%2F%2Fwww.yejs.com.cn%2Fuserfiles%2FDSC05339.JPG')
109 | # test_img('./test_data/new_img1835.jpg')
110 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | from flask_sever import sess, app
2 | from prediction import prediction_result_from_img, init_artificial_neural_network
3 |
4 | if __name__ == '__main__':
5 | model = init_artificial_neural_network(sess);
6 | while True:
7 | try:
8 | img_url = input("请输入图片地址:")
9 | print('您输入的图片地址为:' + img_url)
10 | res = prediction_result_from_img(model, img_url)
11 | except Exception as e:
12 | print('发生了异常:', e)
13 |
--------------------------------------------------------------------------------
/start.sh:
--------------------------------------------------------------------------------
1 | nohup python3 ./flask_sever.py >flask_sever_run_log.log 2>&1 &
--------------------------------------------------------------------------------
/static/images/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/2.png
--------------------------------------------------------------------------------
/static/images/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/3.png
--------------------------------------------------------------------------------
/static/images/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/4.png
--------------------------------------------------------------------------------
/static/images/banana.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/banana.jpg
--------------------------------------------------------------------------------
/static/images/box.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/box.jpg
--------------------------------------------------------------------------------
/static/images/cigar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/cigar.jpg
--------------------------------------------------------------------------------
/static/images/egg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/egg.jpg
--------------------------------------------------------------------------------
/static/images/img_url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/img_url.png
--------------------------------------------------------------------------------
/static/images/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/test.jpg
--------------------------------------------------------------------------------
/static/images/test1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/static/images/test1.jpg
--------------------------------------------------------------------------------
/templates/predict.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 在线测试神经网络垃圾分类识别接口
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
深度学习之垃圾分类api
17 |
18 |
19 |
20 | 在线测试图片.
21 |
22 |
36 |
提交
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
http://10.11.2.17:5000/predict
48 |
post方式访问:上传文件:file
49 |
例如:file:"XXXXXXX"
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
81 |
82 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/test_image/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/test_image/test.jpg
--------------------------------------------------------------------------------
/test_image/test1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlantBiTree/Classify_serverdeploy/a450145f8b2f9f595f7e04025f5e8df2429aebbd/test_image/test1.jpg
--------------------------------------------------------------------------------