記微軟OpenHack機器學習挑戰賽

可健康了發表於2019-05-18

  有幸參加了微軟OpenHack挑戰賽,雖然題目難度不大,但是很有意思,學到了很多東西,還有幸認識了微軟樑健老師,謝謝您的幫助!同時還認識同行的很多朋友,非常高興,把這段難忘的比賽記錄一下~~也分享一下程式碼,給那些沒有參加的朋友,

資料集(文末連結)

首先每支隊伍會收到一個資料集,它是一個登山公司提供的裝備圖片,有登山鎬,鞋子,登山扣,不知道叫什麼的雪地爪?手套,衝鋒衣,安全帶。。。一共12個類別,每個類別幾百個樣本,我們的任務就是對這些圖片分類和識別

簡單看一下:

賽題:

賽題共有6道,簡單描述一下:

1、搭建環境(略過)

2、影像正規化(包括顏色和大小)

3、通過機器學習方法對影像分類,precision>0.8

4、通過深度學習方法對影像分類,precision>0.9

5、部署(略過)

6、目標檢測(用全新的資料集,檢測雪地中的登山者是否帶頭盔!!航拍影像,有點難度~)

 

_______________________________________

下面是每道題目的詳細描述和程式碼


題目2

完成以下任務:

選擇一種基本顏色,例如白色並填充所有圖片尺寸不是1:1比例的影像
不通過直接拉伸的方式,重塑至128x128x3畫素的陣列形狀
確保每個影像的畫素範圍從0到255(包含或[0,255]),也稱為“對比度拉伸”(contrast stretching).

標準化或均衡以確保畫素在[0,255]範圍內.

成功完成的標準
團隊將在Jupyter Notebook中執行一個程式碼單元,繪製原始影像,然後繪製填充後的畫素值歸一化或均衡影像, 展示給教練看.
團隊將在Jupyter notebook 為教練執行一個程式碼單元,顯示的畫素值的直方圖應該在0到255的範圍內(包括0和255).

def normalize(src):
    arr = array(src)
    arr = arr.astype('float')
    # Do not touch the alpha channel
    for i in range(3):
        minval = arr[...,i].min()
        maxval = arr[...,i].max()
        if minval != maxval:
            arr[...,i] -= minval
            arr[...,i] *= (255.0/(maxval-minval))
    arr = arr.astype(uint8)
    return Image.fromarray(arr,'RGB')

import matplotlib.pyplot as plt
from PIL import ImageColor 
from matplotlib.pyplot import imshow
from PIL import Image
from pylab import *
import copy

plt.figure(figsize=(10,10)) #設定視窗大小

# src = Image.open("100974.jpeg")
src = Image.open("rose.jpg")

src_array = array(src)
plt.subplot(2,2,1), plt.title('src')
plt.imshow(src), plt.axis('off')


ar=src_array[:,:,0].flatten()
ag=src_array[:,:,1].flatten()
ab=src_array[:,:,2].flatten()
plt.subplot(2,2,2),  plt.title('src hist')
plt.axis([0,255,0,0.03])
plt.hist(ar, bins=256, normed=1,facecolor='red',edgecolor='r',hold=1) #原始影像直方圖
plt.hist(ag, bins=256, normed=1,facecolor='g',edgecolor='g',hold=1) #原始影像直方圖
plt.hist(ab, bins=256, normed=1,facecolor='b',edgecolor='b') #原g始影像直方圖


dst = normalize(src)
dst_array = array(dst)

plt.subplot(2,2,3), plt.title('dst')
plt.imshow(dst), plt.axis('off')

ar=dst_array[:,:,0].flatten()
ag=dst_array[:,:,1].flatten()
ab=dst_array[:,:,2].flatten()
plt.subplot(2,2,4),  plt.title('dst hist')
plt.axis([0,255,0,0.03])
plt.hist(ar, bins=256, normed=1,facecolor='red',edgecolor='r',hold=1) #原始影像直方圖
plt.hist(ag, bins=256, normed=1,facecolor='g',edgecolor='g',hold=1) #原始影像直方圖
plt.hist(ab, bins=256, normed=1,facecolor='b',edgecolor='b') #原g始影像直方圖
View Code

 

題目3

使用一個非引數化分類方法(參考 參考文件)來建立一個模型,預測新的戶外裝備影像的分類情況,訓練來自挑戰2的預處理過的128x128x3的裝備影像。所使用的演算法可以從scikit-learn庫中挑選現有的非引數化演算法來做分類。向教練展示所提供的測試資料集的精確度,並且精確度分數需要超過80%。

dir_data ="data/preprocess_images/"

equipments = ['axes', 'boots', 'carabiners', 'crampons', 'gloves', 'hardshell_jackets', 'harnesses', 'helmets',
              'insulated_jackets', 'pulleys', 'rope', 'tents']
train_data = [] 
y = [] 

import os
from PIL import Image
for equip_name in equipments:
    dir_equip = dir_data + equip_name
    
    for filename in os.listdir(dir_equip):             
        if(filename.find('jpeg')!=-1):
            name = dir_equip + '/' + filename
            img = Image.open(name).convert('L')
            train_data.append(list(img.getdata()))
            y.append(equip_name)
View Code
from sklearn import svm
from sklearn.cross_validation import train_test_split  

train_X,test_X, train_y, test_y = train_test_split(train_data, y, test_size = 0.3, random_state = 0)

from sklearn import neighbors 
from sklearn.metrics import precision_recall_fscore_support as score
from sklearn.metrics import precision_score,recall_score

clf_knn = neighbors.KNeighborsClassifier(algorithm='kd_tree')  
clf_knn.fit(train_X, train_y)
y_pred = clf_knn.predict(test_X)
View Code
print(__doc__)

import itertools
import numpy as np
import matplotlib.pyplot as plt

from sklearn import svm, datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix

def plot_confusion_matrix(cm, classes,
                          
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

# Compute confusion matrix
# cnf_matrix = confusion_matrix(y_test, y_pred)
np.set_printoptions(precision=2)
confusion_mat = confusion_matrix(test_y, y_pred, labels = equipments)

# Plot non-normalized confusion matrix
plt.figure(figsize=(10,10))
plot_confusion_matrix(confusion_mat, classes=equipments,
                      title='Confusion matrix, without normalization')

# Plot normalized confusion matrix
plt.figure(figsize=(10,10))

plot_confusion_matrix(confusion_mat, classes=equipments, normalize=True,
                      title='Normalized confusion matrix')

plt.show()
View Code

  因為要求精確度>0.8,sklearn中的很多演算法應該都能滿足,我選擇了準確度比較高的KNN來建模,應該足夠用了

 算一下presion和recall,輕鬆超越0.8

 

題目4

挑戰完成標準,使用深度學習模型,如CNN分析複雜資料
團隊將在Jupyter Notebook上為教練執行一個程式碼單元,展示模型的準確度為90%或更高

準確度如果要>0.9,sklearn中的機器學習演算法就很難達到了,關鍵時刻只能上CNN

import matplotlib.pyplot as plt
from PIL import ImageColor 
from matplotlib.pyplot import imshow
from PIL import Image
from pylab import *
dir_data ="data/preprocess_images/"

equipments = ['axes', 'boots', 'carabiners', 'crampons', 'gloves', 'hardshell_jackets', 'harnesses', 'helmets',
              'insulated_jackets', 'pulleys', 'rope', 'tents']
train_data = [] 
y = [] 

import os
from PIL import Image
i=0
for equip_name in equipments:
    dir_equip = dir_data + equip_name
    for filename in os.listdir(dir_equip):             
        if(filename.find('jpeg')!=-1):
            name = dir_equip + '/' + filename
            img = Image.open(name).convert('L')
            train_data.append(array(img).tolist())
            y.append(i)
    i += 1
train_data = np.asarray(train_data)  
View Code
from sklearn import svm
from sklearn.cross_validation import train_test_split  
import numpy as np
import keras
num_classes=12
img_rows=128
img_cols=128
train_X, test_X, train_y, test_y = train_test_split(train_data, y, test_size = 0.3, random_state = 0)

train_X = train_X.reshape(train_X.shape[0], img_rows, img_cols, 1)
test_X = test_X.reshape(test_X.shape[0], img_rows, img_cols, 1)
    
train_X = train_X.astype('float32')
test_X = test_X.astype('float32')
train_X /= 255
test_X /= 255
print('x_train shape:', train_X.shape)
print(train_X.shape[0], 'train samples')
print(test_X.shape[0], 'test samples')

# convert class vectors to binary class matrices
train_y = keras.utils.to_categorical(train_y, num_classes)
test_y = keras.utils.to_categorical(test_y, num_classes)
View Code
from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Flatten
from keras.models import Sequential
from keras.layers import Convolution2D,MaxPooling2D, Conv2D
import keras

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=(128, 128, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
# model.add(Dropout(0.5))
model.add(Dense(12, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(train_X, train_y,
          batch_size=128,
          epochs=50,
          verbose=1,
          validation_data=(test_X, test_y))
score = model.evaluate(test_X, test_y, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
View Code

CNN的混淆矩陣比KNN的好了不少

 訓練了好多次,不斷調整各個卷積層和引數,終於達到了一個比較好的效果~~

 

題目6

使用深度學習框架,基於一個常用的模型,比如Faster R-CNN,訓練一個目標檢測的模型。這個模型需要能夠檢測並且使用方框框出圖片中出現的每一個頭盔。

這道題目首先要自己標註樣本,幾百張影像標註完累的半死。。。這裡我們使用VOTT來標註,它會自動生成一個樣本描述檔案,很方便。Faster R-CNN的程式我們參考了git上的一個紅細胞檢測的專案,https://github.com/THULiusj/CosmicadDetection-Keras-Tensorflow-FasterRCNN,程式碼非常多就不貼了

最後來一張效果圖

本文資料集和VOTT工具 連結:

https://pan.baidu.com/s/1FFw0PLJrrOhwR6J1HexPJA   

提取碼 s242

相關文章