利用AI技術實現(xiàn)城市垃圾的自動分類

上海市作為我國的一線大城市,率先打響了垃圾分類的第一槍,截至到目前為止,垃圾分類工作已開展數(shù)月,由于不少人之前對于垃圾分類都缺乏了解,所以導致許多人對于垃圾分類工作很是苦惱。

圖1 各類垃圾桶
圖2 協(xié)助垃圾分類的志愿者

為了方便人們進行垃圾分類,現(xiàn)如今最常用的做法是在各個垃圾收放點都安排了許多的志愿者協(xié)助大家進行垃圾分類,這無疑大大地增加了人工勞動力。針對此問題,本文將AI技術用于了城市垃圾分類,只需對垃圾進行拍照就可自動識別出它的類別,對于還不了解垃圾分類的童鞋來說,簡直不要太方便。


基于深度學習的城市垃圾分類

數(shù)據(jù)集介紹

本文使用的數(shù)據(jù)集為Gary Thung制作的公開圖像數(shù)據(jù)集,數(shù)據(jù)集下載地址為:
https://github.com/garythung/trashnet/blob/master/data/dataset-resized.zip

實驗數(shù)據(jù)集一共包括五大類:

  • 硬紙板cardboard
  • 玻璃glass
  • 金屬metal
  • 紙paper
  • 塑料plastic

數(shù)據(jù)集圖像尺寸均為512*384像素大小。按照3:1:1的比例將數(shù)據(jù)集劃分為訓練集、驗證集和測試集,即每個類別都包含243張訓練集、80張驗證集和80張測試集。由于數(shù)據(jù)集數(shù)量有限,為了獲得更好的識別效果,文中還利用180度旋轉和鏡像的方式對訓練集進行了擴充,通過數(shù)據(jù)擴充訓練集數(shù)據(jù)量變?yōu)榱嗽鹊?倍,也就是說每個類別都包含972張訓練集圖像。

圖3 數(shù)據(jù)集圖像示例

模型訓練

文中構建了一個八層的卷積神經(jīng)網(wǎng)絡模型,網(wǎng)絡結構圖如下所示:

圖4 網(wǎng)絡結構圖

文中模型的詳細參數(shù)如下所示:

圖5 網(wǎng)絡模型具體參數(shù)

本文在Tensorflow框架下完成了網(wǎng)絡搭建,網(wǎng)絡模型代碼如下:

def Mynet(image, keepprob=0.5):
    # 定義卷積層1,卷積核大小,偏置量等各項參數(shù)參考下面的程序代碼,下同。
    with tf.name_scope("conv1") as scope:
        kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 64], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(image, kernel, [1, 4, 4, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[64]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv1 = tf.nn.relu(bias, name=scope)

        pass

    # LRN層
    lrn1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001/9, beta=0.75, name="lrn1")

    # 最大池化層
    pool1 = tf.nn.max_pool(lrn1, ksize=[1,3,3,1], strides=[1,2,2,1],padding="VALID", name="pool1")

    # 定義卷積層2
    with tf.name_scope("conv2") as scope:
        kernel = tf.Variable(tf.truncated_normal([5,5,64,192], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool1, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[192]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv2 = tf.nn.relu(bias, name=scope)
        pass

    # LRN層
    lrn2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9, beta=0.75, name="lrn2")

    # 最大池化層
    pool2 = tf.nn.max_pool(lrn2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding="VALID", name="pool2")

    # 定義卷積層3
    with tf.name_scope("conv3") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,192,384], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool2, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[384]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv3 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層4
    with tf.name_scope("conv4") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,384,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv3, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv4 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層5
    with tf.name_scope("conv5") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,256,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv4, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv5 = tf.nn.relu(bias, name=scope)
        pass

    # 最大池化層
    pool5 = tf.nn.max_pool(conv5, ksize=[1,3,3,1], strides=[1,2,2,1], padding="VALID", name="pool5")

    # 全連接層
    flatten = tf.reshape(pool5, [-1, 15*11*256])

    weight1 = tf.Variable(tf.truncated_normal([15*11*256, 4096], mean=0, stddev=0.01))

    fc1 = tf.nn.sigmoid(tf.matmul(flatten, weight1))

    dropout1 = tf.nn.dropout(fc1, keepprob)

    weight2 = tf.Variable(tf.truncated_normal([4096, 4096], mean=0, stddev=0.01))

    fc2 = tf.nn.sigmoid(tf.matmul(dropout1, weight2))

    dropout2 = tf.nn.dropout(fc2, keepprob)

    weight3 = tf.Variable(tf.truncated_normal([4096, 5], mean=0, stddev=0.01))

    fc3 = tf.nn.sigmoid(tf.matmul(dropout2, weight3))

    return fc3

利用訓練集對模型進行訓練,共訓練了200個epoch,如圖5所示為網(wǎng)絡訓練結果。

圖6 網(wǎng)絡訓練結果

模型測試

利用測試集對網(wǎng)絡模型進行精度測試,最終的測試精度為77.75%,本文還增添了模型預測結果可視化顯示功能,如下所示為模型的測試結果示例圖,模型將預測結果在圖片上方用英文名稱顯示。

可以看出,本文所搭建的模型對于大部分城市垃圾都可以做出正確分類識別,表明了本文的方法的可行性。

后記

本文所搭建的模型測試精度目前只有77.75%,精度仍然還有很大的上升空間,通過分析我認為主要以下幾點原因:

  • 在實際生活中,城市垃圾的種類是十分繁多的,而本文實驗中的數(shù)據(jù)量較少,盡管后續(xù)做了數(shù)據(jù)增強處理,使得訓練集數(shù)據(jù)量達到了4860張,看起來這一數(shù)字比較可觀,但是對于深度學習模型來說,數(shù)據(jù)量仍然過少,尤其是對于數(shù)據(jù)比較復雜的城市垃圾來說,這一數(shù)據(jù)量是難遠遠不夠的。
  • 不同的數(shù)據(jù)集在不同的模型上表現(xiàn)效果也是不一致的,在后續(xù),本文所搭建的深度學習網(wǎng)絡模型還亟待進一步的優(yōu)化。

本人知識有限,歡迎各位感興趣的同仁提出寶貴意見和共同探討,本人微信號:liuwei646102318,添加的時候請注明是從簡書加的,希望共同成長。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容