├── .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 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/sever.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 66 | 67 | 68 | 88 | 89 | 90 | 110 | 111 | 112 | 132 | 133 | 148 | 149 | 150 | 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 | 229 | 230 | 231 | 232 | 234 | 235 | 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 | 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 |
23 |
24 |
选择文件
25 |
26 |
27 | 28 | 31 |
32 |
33 | 34 |
35 |
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 --------------------------------------------------------------------------------