0 前言
🔥 優質競賽項目系列,今天要分享的是
🚩 opencv python 深度學習垃圾分類系統
🥇學長這里給一個題目綜合評分(每項滿分5分)
- 難度系數:3分
- 工作量:3分
- 創新點:4分
這是一個較為新穎的競賽課題方向,學長非常推薦!
🧿 更多資料, 項目分享:
https://gitee.com/dancheng-senior/postgraduate
課題簡介
如今,垃圾分類已成為社會熱點話題。其實在2019年4月26日,我國住房和城鄉建設部等部門就發布了《關于在全國地級及以上城市全面開展生活垃圾分類工作的通知》,決定自2019年起在全國地級及以上城市全面啟動生活垃圾分類工作。到2020年底,46個重點城市基本建成生活垃圾分類處理系統。
人工垃圾分類投放是垃圾處理的第一環節,但能夠處理海量垃圾的環節是垃圾處理廠。然而,目前國內的垃圾處理廠基本都是采用人工流水線分揀的方式進行垃圾分揀,存在工作環境惡劣、勞動強度大、分揀效率低等缺點。在海量垃圾面前,人工分揀只能分揀出極有限的一部分可回收垃圾和有害垃圾,絕大多數垃圾只能進行填埋,帶來了極大的資源浪費和環境污染危險。
隨著深度學習技術在視覺領域的應用和發展,讓我們看到了利用AI來自動進行垃圾分類的可能,通過攝像頭拍攝垃圾圖片,檢測圖片中垃圾的類別,從而可以讓機器自動進行垃圾分揀,極大地提高垃圾分揀效率。
基于深度學習的垃圾分類系統,是非常好的畢業設計課題
一、識別效果
老樣子, 廢話不多說,先展示圖像垃圾分類的識別效果
訓練模型精度:
可以看到,只迭代了10輪精度達到87.50%,而且沒有出現過擬合現象
我最高訓練達到96%,迭代200輪
識別結果:
實際驗證正確率還是很高的。
二、實現
1.數據集
該數據集包含了 2507 個生活垃圾圖片。數據集的創建者將垃圾分為了 6 個類別,分別是:
如下所示:
一共6類垃圾, 比如玻璃類的如下:
塑料類的如下:
其他的不列舉了。
2.實現原理和方法
使用深度殘差網絡resnet50作為基石,在后續添加需要的層以適應不同的分類任務
模型的訓練需要用生成器將數據集循環寫入內存,同時圖像增強以泛化模型
使用不包含網絡輸出部分的resnet50權重文件進行遷移學習,只訓練我們在5個stage后增加的層
需要的第三方庫主要有tensorflow1.x,keras,opencv,Pillow,scikit-learn,numpy
安裝方式很簡單,打開terminal,例如:pip install numpy -i
https://pypi.tuna.tsinghua.edu.cn/simple
數據集與權重文件比較大,所以沒有上傳
如果環境配置方面有問題或者需要數據集與模型權重文件,可以在評論區說明您的問題,我將遠程幫助您
3.網絡結構
這里我只使用了resnet50的5個stage,后面的輸出部分需要我們自己定制,網絡的結構圖如下:
stage5后我們的定制網絡如下:
?
"""定制resnet后面的層"""def custom(input_size,num_classes,pretrain):# 引入初始化resnet50模型base_model = ResNet50(weights=pretrain,include_top=False,pooling=None,input_shape=(input_size,input_size, 3),classes=num_classes)#由于有預權重,前部分凍結,后面進行遷移學習for layer in base_model.layers:layer.trainable = False#添加后面的層x = base_model.outputx = layers.GlobalAveragePooling2D(name='avg_pool')(x)x = layers.Dropout(0.5,name='dropout1')(x)#regularizers正則化層,正則化器允許在優化過程中對層的參數或層的激活情況進行懲罰#對損失函數進行最小化的同時,也需要讓對參數添加限制,這個限制也就是正則化懲罰項,使用l2范數x = layers.Dense(512,activation='relu',kernel_regularizer= regularizers.l2(0.0001),name='fc2')(x)x = layers.BatchNormalization(name='bn_fc_01')(x)x = layers.Dropout(0.5,name='dropout2')(x)#40個分類x = layers.Dense(num_classes,activation='softmax')(x)model = Model(inputs=base_model.input,outputs=x)#模型編譯model.compile(optimizer="adam",loss = 'categorical_crossentropy',metrics=['accuracy'])return model
網絡的訓練是遷移學習過程,使用已有的初始resnet50權重(5個stage已經訓練過,卷積層已經能夠提取特征),我們只訓練后面的全連接層部分,4個epoch后再對較后面的層進行訓練微調一下,獲得更高準確率,訓練過程如下:
?
class Net():def __init__(self,img_size,gar_num,data_dir,batch_size,pretrain):self.img_size=img_sizeself.gar_num=gar_numself.data_dir=data_dirself.batch_size=batch_sizeself.pretrain=pretrain
def build_train(self):"""遷移學習"""model = resnet.custom(self.img_size, self.gar_num, self.pretrain)model.summary()train_sequence, validation_sequence = genit.gendata(self.data_dir, self.batch_size, self.gar_num, self.img_size)epochs=4model.fit_generator(train_sequence,steps_per_epoch=len(train_sequence),epochs=epochs,verbose=1,validation_data=validation_sequence,max_queue_size=10,shuffle=True)#微調,在實際工程中,激活函數也被算進層里,所以總共181層,微調是為了重新訓練部分卷積層,同時訓練最后的全連接層layers=149learning_rate=1e-4for layer in model.layers[:layers]:layer.trainable = Falsefor layer in model.layers[layers:]:layer.trainable = TrueAdam =adam(lr=learning_rate, decay=0.0005)model.compile(optimizer=Adam, loss='categorical_crossentropy', metrics=['accuracy'])model.fit_generator(train_sequence,steps_per_epoch=len(train_sequence),epochs=epochs * 2,verbose=1,callbacks=[callbacks.ModelCheckpoint('./models/garclass.h5',monitor='val_loss', save_best_only=True, mode='min'),callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1,patience=10, mode='min'),callbacks.EarlyStopping(monitor='val_loss', patience=10),],validation_data=validation_sequence,max_queue_size=10,shuffle=True)print('finish train,look for garclass.h5')
最后
🧿 更多資料, 項目分享:
https://gitee.com/dancheng-senior/postgraduate