原博地址laboo.top/2018/12/02/…git
在傳統編程中, 圖像識別一直是一個難點, 雖然人能輕鬆作到, 可是用邏輯來描述這個過程, 並轉換成程序是很難的。機器學習的出現讓圖像識別技術有了突破性的進展, 卷積神經網絡的出現, 又使圖像識別更上了一次層次。github
卷積神經網絡由一個或多個卷積層和頂端的全連通層組成, 這一結構使得卷積神經網絡可以利用輸入數據的二維結構。與其餘深度學習結構相比,卷積神經網絡在圖像和語音識別方面可以給出更好的結果。編程
這裏咱們使用卷積神經網絡對人臉進行性別識別, 項目中使用了TensorFlow
機器學習庫。網絡
機器學習的基礎就是大量的數據。我之前從網上爬了一萬張證件照, 如今正好用上, 做爲訓練數據。 簡便的也能夠從谷歌直接搜搜索 男(女)性證件照
也能夠獲得而且有標籤的數據。 因爲我收集的照片沒有標籤, 因而我花了一點時間從其中人工選出男女照片各200張並打上標記。機器學習
爲了使識別更加準確, 項目中利用openCV
裁剪出人臉部分的圖像, 並縮放至28*28
大小。ide
recognizer = cv2.CascadeClassifier("model/haarcascade_frontalface_default.xml")
crop(img_path):
try:
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = recognizer.detectMultiScale(gray)
if len(faces):
x, y, w, h = faces[0]
c_img = img[y:y + h, x:x + w]
return cv2.resize(c_img, (28, 28), interpolation=cv2.INTER_AREA)
except:
pass
return None
複製代碼
對全部的數據都進行這樣處理, 結果以下: 函數
最後咱們還須要清理異常的數據, 過一遍訓練集, 把其中沒有定位到人臉的圖片去除掉。讀取訓練數據。學習
def read_img(files):
arr = []
for file in files:
img = Image.open("%s" % file)
pix = img.load()
view = np.zeros((IMAGE_H, IMAGE_W, 1), dtype=np.float)
for x in range(IMAGE_H):
for y in range(IMAGE_W):
r, g, b = pix[y, x]
view[x, y, 0] = (r + g + b) // 3
arr.append(view)
return np.array(arr)
複製代碼
這裏對訓練圖像灰度化, 而且將訓練數據中的一小部分做爲驗證集。測試
開始建立模型。
model = keras.Sequential([
keras.layers.Conv2D(32, (3, 3), input_shape=(IMAGE_W, IMAGE_H, 1), strides=(1, 1), activation='relu'),
keras.layers.MaxPool2D(pool_size=(2, 2)),
keras.layers.Conv2D(64, (3, 3), strides=(1, 1), activation='relu'),
keras.layers.MaxPool2D(pool_size=(2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dropout(0.2),
keras.layers.Dense(2, activation=tf.nn.softmax)
])
複製代碼
選擇適當的優化器和損失函數編譯模型。
model.compile(optimizer=tf.train.AdamOptimizer(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
複製代碼
開始訓練模型。
model.fit(x=train_x,
y=train_y,
batch_size=32,
epochs=30,
verbose=1,
callbacks=my_callbacks,
validation_split=0.05,
shuffle=True
)
複製代碼
這裏使用matplotlib來顯示測試圖片及結果。
predictions = model.predict(test_x)
class_names = ["Female", "Male"]
plt.figure(figsize=(12, 6))
for i in range(min(9, len(test_y))):
result = predictions[i]
max_label = int(np.argmax(result))
correct_label = int(np.argmax(test_y[i]))
plt.subplot(3, 6, 2 * i + 1)
plt.grid(False)
plt.xticks([])
plt.yticks([])
img = test_x.reshape(test_x.shape[0], IMAGE_W, IMAGE_H)[i]
plt.imshow(img, cmap="gray")
plt.xlabel("{} - prob:{:2.0f}%".format(class_names[max_label], 100 * np.max(result)))
plt.subplot(3, 6, 2 * i + 2)
plt.grid(False)
plt.yticks([])
plt.ylim([0, 1])
bar = plt.bar(range(2), result)
bar[max_label].set_color('red')
bar[correct_label].set_color('green')
plt.show()
複製代碼
臉部頭像右側的兩列分別表明
女性機率
和
男性機率
。 這裏咱們看到全都對了, 正確率很是高。 模型並不複雜, 大部分工做都在收集數據和調整訓練參數上, 這也體現出了卷積神經網絡對圖像強大的處理能力。
歡迎關注個人博客公衆號