1. 程式人生 > >震驚!讓90%的程式設計師一看就會的入門級AI專案!

震驚!讓90%的程式設計師一看就會的入門級AI專案!

隨著AI的發展,美國橡樹嶺國家實驗室的一些專家預測,到2040年,AI技術將會強大到足以替代程式設計師。AI技術將會強大到足以替代程式設計師,AI編寫軟體將比人類程式設計師更好、更快。換句話說,軟體編寫的軟體比人類編寫的更好。

這是怎麼發生的?AI能真正學會如何做需要高度創造性的智力工作嗎?畢竟創造性一直被認為是人類特有的。AI能學到的東西會比我們教它的更多嗎?

穩住,別慌今天本文將分享一篇AI入門實戰的專案經驗分享,專門為對於沒有動過手的同學準備,以此來啟發新手們如何開動,瞭解AI技術~

漢字書法識別入門

前段時間參加了一次TinyMind舉辦的漢字書法識別挑戰賽,說是挑戰賽其實就是一場練習賽。為一些剛剛入門的同學和沒有比賽經驗的同學提供了一個探索影象識別領域的平臺。我目前是暫列榜首(沒想到轉眼就被超越了-。-),所以把自己的思路和想法稍微做一個分享,給有需要的人提供一個base line。

先來看資料集~~

100個漢字的訓練集
10000張書法圖片的測試集

上面的訓練集總共有100個漢字,每一個漢字都有400張不同字型的圖片,資料量上來看算是一個比較小的資料集。

等等,看到的確定是漢字嗎,第一眼望過去我是真的emmmmm.....甲骨文,篆體各種字型都冒出來了。先喝口水冷靜一下,仔細看一看發現圖片都是gray的。想了一想突然覺得這個和mnist並沒有太大的區別只是字型更加複雜一些,可能要用稍微深一點的網路來訓練。

圖片看完了,那麼開始擼程式碼了。分析終究是分析,還是實踐才能說明一切。

資料集劃分

競賽中只給了train和test,所以需要自己手動劃分一個val來做模型訓練的驗證測試。在這裡簡單說明一下經常用的兩種劃分資料集的方法。

  • 本地劃分

  • 記憶體劃分

本地劃分:圖片是按照資料夾分類的,所以只需要從每個資料夾中按ratio抽取部分圖片到val中即可,當然不要忘記了shuffle。
記憶體劃分:把所有圖片和標籤讀進記憶體中,存為list或者array然後shuffle後按長度劃分。前提是把資料讀進去記憶體不會爆炸掉。記憶體劃分只適合小型資料集,不然會Boom!!!

注:劃分資料集的時候一定要打亂資料,shuffle很重要!!!

def move_ratio(data_list, original_str, replace_str):
    for x in data_list:
        fromImage = Image.open(x)
        x = x.replace(original_str, replace_str)
        fromImage.save(x)

注:這裡只給出部分程式碼。

for d in $(ls datadir); do                        
    for f in $(ls datadir/$d | shuf | head -n 100 ); do
        mkdir -p valid_dir/$d/
        mv datadir/$d/$f valid_dir/$d/;
    done;
done

注:這裡引用dwSun的linux shell指令碼,如果想用簡單指令碼實現也可以採用他的程式碼~

模型建立與資料預處理

對於CNN網路來說,大的資料集對應大的訓練樣本,如果小的資料集想要用深層次的網路來訓練的話,那麼必不可少的一步就是資料增強。

資料增強的大部分方法,所有深度學習框架都已經封裝好了。這裡我採用的是keras自帶的資料增強方法。

from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
    # horizontal_flip=True,
    width_shift_range=0.15,
    height_shift_range=0.15,
    rescale=1 / 255
)

由於漢字是具有筆畫順序的,所以做了翻轉以後訓練的效果不是很好。這裡就做了一個寬度和高度的偏移,由於給的資料集圖片長寬不是固定的而且字型的內容也是有長有短。所以用這兩種增強方式可以提高模型的準確率,結果測試這兩種方式還是有效的。

資料處理完了,那麼下面就是我們可愛的CNN網路模型了

cnn一把梭

嗯,就是幹。

1# bn + prelu
 2def bn_prelu(x):
 3    x = BatchNormalization()(x)
 4    x = PReLU()(x)
 5    return x
 6# build baseline model
 7def build_model(out_dims, input_shape=(128, 128, 1)):
 8    inputs_dim = Input(input_shape)
 9    x = Conv2D(32, (3, 3), strides=(2, 2), padding='valid')(inputs_dim)
10    x = bn_prelu(x)
11    x = Conv2D(32, (3, 3), strides=(1, 1), padding='valid')(x)
12    x = bn_prelu(x)
13    x = MaxPool2D(pool_size=(2, 2))(x)
14    x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
15    x = bn_prelu(x)
16    x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
17    x = bn_prelu(x)
18    x = MaxPool2D(pool_size=(2, 2))(x)
19    x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
20    x = bn_prelu(x)
21    x = MaxPool2D(pool_size=(2, 2))(x)
22    x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
23    x = bn_prelu(x)
24    x = AveragePooling2D(pool_size=(2, 2))(x)
25    x_flat = Flatten()(x)
26    fc1 = Dense(512)(x_flat)
27    fc1 = bn_prelu(fc1)
28    dp_1 = Dropout(0.3)(fc1)
29    fc2 = Dense(out_dims)(dp_1)
30    fc2 = Activation('softmax')(fc2)
31    model = Model(inputs=inputs_dim, outputs=fc2)
32    return model

這裡用了6個簡單的卷積層,和PRelu+bn層。

下面是一個比較大的模型ResNet50,模型是已經merge在了keras的applications中,可以直接用。不過需要調整分類層。

 1def resnet50_100(feat_dims, out_dims):
 2    # resnett50 only have a input_shape=(128, 128, 3), if use resnet we must change
 3    # shape at least shape=(197, 197, 1)
 4    resnet_base_model = ResNet50(include_top=False, weights=None, input_shape=(128, 128, 1))
 5    # get output of original resnet50
 6    x = resnet_base_model.get_layer('avg_pool').output
 7    x = Flatten()(x)
 8    fc = Dense(feat_dims)(x)
 9    x = bn_prelu(fc)
10    x = Dropout(0.5)(x)
11    x = Dense(out_dims)(x)
12    x = Activation("softmax")(x)
13    # buid myself model
14    input_shape = resnet_base_model.input
15    output_shape = x
16    resnet50_100_model = Model(inputs=input_shape, outputs=output_shape)
17    return resnet50_100_model

好了,煉丹爐有了接下來就是你懂的。

訓練模型

訓練模型和調參真的是一個技術活,這裡我跑了共40個epoch。思路只有一個那就是先把train的資料跑到loss下降並且先過擬合再說。只要過擬合了後面的一切都好調整了,如果訓練資料都不能到過擬合或者99以上那麼要仔細想想資料量夠不夠和模型的選擇了。

可以很清楚的看出來,訓練資料集已經過擬合了。我用的優化器是sgd,學習率設定的是lr=0.01。val_acc可以跑到了0.94左右,這是一個比較正常的訓練水平。還可以進一步的提高。

提高方法

  • 資料增強:採取其他的資料增強方法進一步擴大訓練資料,這裡可以採用GAN來生成近似於真實圖片的資料。

  • 衰減學習率:當到達一定epoch的時候,loss不再下降了這個時候可以通過減小學習率的方法進一步訓練。

  • 模型融合:模型融合的方法在大部分資料集上都會有所提高,這個是最常用的一種競賽方式。

以上就是我自己做的流程和思路,提交結果和評測的程式碼請新增下面微信領取,有興趣參加比賽練手的同學可以參考一下。

好多小夥伴是從開發或者是其他工程上轉到AI的,所以下面我給有需要的同學列舉出一些必要的基礎知識點:

 

數學:線性代數和概率論是必須要會的,而且基本的概念和計算都要懂。可以把高數,線性代數和概率論看一遍,這裡推薦李航的統計學習方法。

影象處理:如果是做影象方面的小夥伴,那麼需要把岡薩雷斯的影象處理那本鉅作看一遍,需要懂基本的影象概念和基本方法。

還有機器學習 深度學習經典書、如果能把這幾本書完全吃透那也很厲害了,當然學習知識點的途徑還有很多。

  • 學習社群

  • Google

  • TinyMind

如果想深入學習的話,我推薦還是報名實訓營,讓更有經驗的大咖導師為你指路,效率和效果都會翻倍!

在這裡推薦 CSDN 學院出品的《人工智慧工程師直通車》實訓營,目的是:通過 120 天的實戰,將學員培養達到具備一年專案經驗的人工智慧工程師水平。CSDN 百天計劃課程共分為 3 個階段,4 個月完成。

五分鐘瞭解課程點選:https://www.v5kf.com/public/chat/chat?sid=148176&entry=5&ref=link&accountid=242d003016152

聯絡 CSDN 學院職場規劃師,獲取一對一專屬服務(包括:IT 職場規劃服務/專屬折扣)

為什麼報名CSDN學院?

很多學員都曾苦惱,工作中缺乏“好師傅”,很多Bug,也都得絞盡腦汁自己解決。在全棧特訓營,這些問題都將不存在。

我們採取講師+課程助教的服務模式。

授課的兩位老師分別是:中國科學院大學計算機與控制學院副教授卿來雲老師、和計算機視覺領域處理大牛智亮老師。兩位老師一個偏重理論知識、演算法推倒;一個偏重實際操作,實戰經驗,可以全方面的為學員提供知識的講解。 

課程助教將會帶領你一起攻克專案,Review你的程式碼並給出意見。最後,課程助教會帶你們一起進行專案最後上線路演,並接受導師的點評。

基礎部分大綱
高階部分大綱

對於課業完成優秀的同學,CSDN 學院還將提供名企推薦,看到這裡,你想不想踩在過來人的肩膀上,輕鬆實現轉型人工智慧工程師呢?

不妨新增 CSDN 學院小姐姐的微信聊一聊吧,報程式人生的粉絲,還將獲得千元優惠券哦。

聯絡 CSDN 學院職場規劃師,獲取一對一專屬服務(包括:IT 職場規劃服務/專屬折扣)

最後,祝願所有的朋友能學有所成~  

閱讀原文