機器學習——森林火災圖片識別


(一)選題背景:森林火災,是指失去人為控制,在林地內自由蔓延和擴展,對森林、森林生態系統和人類帶來一定危害和損失的林火行為。森林火災是一種突發性強、破壞性大、處置救助較為困難的自然火災。而近年來由於溫室效應加劇,森林火災頻發。在這樣的情境下,做好預防是必要的,要做到24小時全天候大范圍的監視,衛星、無人機巡查是比較好措施,對於無人機巡查,機器是如何判斷當前地區發生火災,計算機視覺應該是其中一項重要技術,於是設計了對森林火災圖片識別的小程序,希望通過此次的設計對計算機視覺有所理解。

 

(二)機器學習設計案例設計方案:從網站中下載相關的數據集,對數據集進行整理,在python的環境中,給數據集中的文件打上標簽,對數據進行預處理,利用keras,構建網絡,訓練模型,導入圖片測試模型


參考來源:kaggle關於標簽學習的討論區

數據集來源:kaggle,網址:https://www.kaggle.com/

 

(三)機器學習的實現步驟:

 


一、二分類


1.下載數據集

 

2.導入需要用到的庫

 1 #導入需要用到的庫
 2 import numpy as np 
 3 import pandas as pd
 4 import os
 5 import tensorflow as tf
 6 import matplotlib.pyplot as plt
 7 from pathlib import Path
 8 from sklearn.model_selection import train_test_split
 9 from keras.models import Sequential
10 from keras.layers import Activation
11 from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
12 from keras.applications.resnet import preprocess_input
13 from keras_preprocessing.image import ImageDataGenerator
14 from keras.models import load_model
15 from keras.preprocessing.image import load_img, img_to_array
16 from keras import optimizers

3.遍歷數據集中的文件,將路徑數據和標簽數據生成DataFrame

 1 dir = Path('D:/python的課程設計1/fire')
 2 
 3 # 用glob遍歷在dir路徑中所有jpg格式的文件,並將所有的文件名添加到filepaths列表中
 4 filepaths = list(dir.glob(r'**/*.jpg'))
 5 
 6 # 將文件中的分好的小文件名(種類名)分離並添加到labels的列表中
 7 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))
 8 
 9 # 將filepaths通過pandas轉換為Series數據類型
10 filepaths = pd.Series(filepaths, name='FilePaths').astype(str)
11 
12 # 將labels通過pandas轉換為Series數據類型
13 labels = pd.Series(labels, name='Labels').astype(str)
14 
15 # 將filepaths和Series兩個Series的數據類型合成DataFrame數據類型
16 df = pd.merge(filepaths, labels, right_index=True, left_index=True)
17 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
18 df = df.sample(frac=1).reset_index(drop=True)
19 #查看形成的DataFrame的數據
20 df

 

 

 

 

4.查看圖像以及對應的標簽

 1 #查看圖像以及對應的標簽
 2 fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))
 3 
 4 for i, a in enumerate(ax.flat):
 5     a.imshow(plt.imread(df.FilePaths[i]))
 6     a.set_title(df.Labels[i])
 7     
 8 plt.tight_layout()
 9 plt.show()
10 
11 #查看各個標簽的圖片張數
12 df['Labels'].value_counts(ascending=True)

 

 5.由總的數據集生成分別生成訓練集,測試集和驗證集

 1 #將總數據按10:1的比例分配給X_train, X_test
 2 X_train, X_test = train_test_split(df, test_size=0.1, stratify=df['Labels'])
 3 
 4 print('Shape of Train Data: ', X_train.shape)
 5 print('Shape of Test Data: ', X_test.shape)
 6 
 7 # 將總數據按5:1的比例分配給X_train, X_train
 8 X_train, X_val = train_test_split(X_train, test_size=0.2, stratify=X_train['Labels'])
 9 
10 print('Shape of Train Data: ', X_train.shape)
11 print('Shape of Val Data: ', X_val.shape)
12 
13 # 查看各個標簽的圖片張數
14 X_train['Labels'].value_counts(ascending=True)

 

 6.圖像預處理

 1 # 批量大小
 2 BATCH_SIZE = 32
 3 # 輸入圖片的大小
 4 IMG_SIZE = (224, 224)
 5 
 6 # 圖像預處理
 7 img_data_gen = ImageDataGenerator(preprocessing_function=preprocess_input)
 8 
 9 X_train = img_data_gen.flow_from_dataframe(dataframe=X_train,
10                                           x_col='FilePaths',
11                                           y_col='Labels',
12                                           target_size=IMG_SIZE,
13                                           color_mode='rgb',
14                                           class_mode='binary',
15                                           batch_size=BATCH_SIZE,
16                                           seed=42)
17 
18 X_val = img_data_gen.flow_from_dataframe(dataframe=X_val,
19                                           x_col='FilePaths',
20                                           y_col='Labels',
21                                           target_size=IMG_SIZE,
22                                           color_mode='rgb',
23                                           class_mode='binary',
24                                           batch_size=BATCH_SIZE,
25                                           seed=42)
26 X_test = img_data_gen.flow_from_dataframe(dataframe=X_test,
27                                           x_col='FilePaths',
28                                           y_col='Labels',
29                                           target_size=IMG_SIZE,
30                                           color_mode='rgb',
31                                           class_mode='binary',
32                                           batch_size=BATCH_SIZE,
33                                           seed=42)

7.查看經過處理的圖片以及它的binary標簽

#查看經過處理的圖片以及它的binary標簽
fit, ax = plt.subplots(nrows=2, ncols=3, figsize=(13,7))

for i, a in enumerate(ax.flat):
    img, label = X_train.next()
    a.imshow(img[0],)
    a.set_title(label[0])

plt.tight_layout()
plt.show()

 

 8.構建神經網絡並對模型進行訓練

#構建神經網絡
model = Sequential()
# 數據歸一化處理
model.add(tf.keras.layers.experimental.preprocessing.Rescaling(1./255))

# 1.Conv2D層,32個過濾器
model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(224, 224, 3)))#圖形是彩色,‘rgb’,所以設置3
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))

# 2.Conv2D層,64個過濾器
model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))

# 3.Conv2D層,128個過濾器
model.add(Conv2D(filters=128, kernel_size=(3,3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))

# 將輸入層的數據壓縮成1維數據,全連接層只能處理一維數據
model.add(Flatten())

# 全連接層
model.add(Dense(256))
model.add(Activation('relu'))

# 減少過擬合
model.add(Dropout(0.5))

# 全連接層
model.add(Dense(1))
model.add(Activation('sigmoid'))

# 模型編譯
model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
              loss="categorical_crossentropy", 
              metrics=["accuracy"])

#利用批量生成器訓練模型
h1 = model.fit(X_train, validation_data=X_val,
epochs=30, )
#保存模型
model.save('t1')

 

 

 9.繪制損失曲線和精度曲線圖

 1 accuracy = h1.history['accuracy']
 2 loss = h1.history['loss']
 3 val_loss = h1.history['val_loss']
 4 val_accuracy = h1.history['val_accuracy']
 5 plt.figure(figsize=(17, 7))
 6 plt.subplot(2, 2, 1)
 7 plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
 8 plt.plot(range(30), val_accuracy, label='Validation Accuracy')
 9 plt.legend(loc='lower right')
10 plt.title('Accuracy : Training vs. Validation ')
11 plt.subplot(2, 2, 2)
12 plt.plot(range(30), loss,'bo' ,label='Training Loss')
13 plt.plot(range(30), val_loss, label='Validation Loss')
14 plt.title('Loss : Training vs. Validation ')
15 plt.legend(loc='upper right')
16 plt.show()

 

 10.導入圖片進行預測

from PIL import Image
def con(file,outdir,w=224,h=224):
    img1=Image.open(file)
    img2=img1.resize((w,h),Image.BILINEAR)
    img2.save(os.path.join(outdir,os.path.basename(file)))
file='D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg'
con(file,'D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/')
model=load_model('t1')
img_path='D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg'
img = load_img(img_path)
img = img_to_array(img)
img = np.expand_dims(img, axis=0)
out = model.predict(img)
if out[0]>0.5:
        print('是火災的概率為',out[0])
else:
         print('不是火災')
img=plt.imread('D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg')
plt.imshow(img)

 

 二、多分類

1.准備數據集

 

 2.遍歷數據集中的文件,將路徑數據和標簽數據生成DataFrame

 1 dir = Path('D:/python的課程設計1')
 2 
 3 # 用glob遍歷在dir路徑中所有jpg格式的文件,並將所有的文件名添加到filepaths列表中
 4 filepaths = list(dir.glob(r'**/*.jpg'))
 5 
 6 # 將文件中的分好的小文件名(種類名)分離並添加到labels的列表中
 7 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))
 8 
 9 # 將filepaths通過pandas轉換為Series數據類型
10 filepaths = pd.Series(filepaths, name='FilePaths').astype(str)
11 
12 # 將labels通過pandas轉換為Series數據類型
13 labels = pd.Series(labels, name='Labels').astype(str)
14 
15 # 將filepaths和Series兩個Series的數據類型合成DataFrame數據類型
16 df = pd.merge(filepaths, labels, right_index=True, left_index=True)
17 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
18 df = df.sample(frac=1).reset_index(drop=True)

#查看形成的DataFrame的數據
df

 

 

3.查看圖像以及對應的標簽

1 fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))
2 
3 for i, a in enumerate(ax.flat):
4     a.imshow(plt.imread(df.FilePaths[i]))
5     a.set_title(df.Labels[i])
6     
7 plt.tight_layout()
8 plt.show()

 

 4.由總的數據集生成分別生成訓練集,測試集和驗證集

#將總數據按10:1的比例分配給X_train, X_test
X_train, X_test = train_test_split(df, test_size=0.1, stratify=df['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Test Data: ', X_test.shape)

# 將總數據按5:1的比例分配給X_train, X_train
X_train, X_val = train_test_split(X_train, test_size=0.2, stratify=X_train['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Val Data: ', X_val.shape)

# 查看各個標簽的圖片張數
X_train['Labels'].value_counts(ascending=True)

 

 5.圖像預處理

 1 # 批量的大小
 2 BATCH_SIZE = 32
 3 # 輸入圖片的大小
 4 IMG_SIZE = (224, 224)
 5 
 6 # 圖像預處理
 7 img_data_gen = ImageDataGenerator(preprocessing_function=preprocess_input)
 8 
 9 
10 X_train = img_data_gen.flow_from_dataframe(dataframe=X_train,
11                                           x_col='FilePaths',
12                                           y_col='Labels',
13                                           target_size=IMG_SIZE,
14                                           color_mode='rgb',
15                                           class_mode='categorical',
16                                           batch_size=BATCH_SIZE,
17                                           seed=42)
18 
19 X_val = img_data_gen.flow_from_dataframe(dataframe=X_val,
20                                           x_col='FilePaths',
21                                           y_col='Labels',
22                                           target_size=IMG_SIZE,
23                                           color_mode='rgb',
24                                           class_mode='categorical',
25                                           batch_size=BATCH_SIZE,
26                                           seed=42)
27 X_test = img_data_gen.flow_from_dataframe(dataframe=X_test,
28                                           x_col='FilePaths',
29                                           y_col='Labels',
30                                           target_size=IMG_SIZE,
31                                           color_mode='rgb',
32                                           class_mode='categorical',
33                                           batch_size=BATCH_SIZE,
34                                           seed=42)

 

 6.查看經過處理的圖片以及它的one-hot標簽

1 fit, ax = plt.subplots(nrows=2, ncols=3, figsize=(13,7))
2 
3 for i, a in enumerate(ax.flat):
4     img, label = X_train.next()
5     a.imshow(img[0],)
6     a.set_title(label[0])
7 
8 plt.tight_layout()
9 plt.show()

 

 7.構建神經網絡並訓練模型

 1 model = Sequential()
 2 # 數據歸一化處理
 3 model.add(tf.keras.layers.experimental.preprocessing.Rescaling(1./255))
 4 
 5 # 1.Conv2D層,32個過濾器
 6 model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(224, 224, 3)))#圖形是彩色,‘rgb’,所以設置3
 7 model.add(Activation('relu'))
 8 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
 9 
10 # 2.Conv2D層,64個過濾器
11 model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same'))
12 model.add(Activation('relu'))
13 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
14 
15 # 3.Conv2D層,128個過濾器
16 model.add(Conv2D(filters=128, kernel_size=(3,3), padding='same'))
17 model.add(Activation('relu'))
18 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
19 
20 # 將輸入層的數據壓縮成1維數據,全連接層只能處理一維數據
21 model.add(Flatten())
22 
23 # 全連接層
24 model.add(Dense(256))
25 model.add(Activation('relu'))
26 
27 # 減少過擬合
28 model.add(Dropout(0.5))
29 
30 # 全連接層
31 model.add(Dense(4))#需要識別的有4個種類
32 model.add(Activation('softmax'))#softmax是基於二分類函數sigmoid的多分類函數
33 
34 # 模型編譯
35 model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
36               loss="categorical_crossentropy", 
37               metrics=["accuracy"])
38 #利用批量生成器訓練模型
39 h1 = model.fit(X_train, validation_data=X_val,
40                epochs=30, )
41 #保存模型
42 model.save('h21')

8.繪制損失曲線和精度曲線圖

 1 accuracy = h1.history['accuracy']
 2 loss = h1.history['loss']
 3 val_loss = h1.history['val_loss']
 4 val_accuracy = h1.history['val_accuracy']
 5 plt.figure(figsize=(17, 7))
 6 plt.subplot(2, 2, 1)
 7 plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
 8 plt.plot(range(30), val_accuracy, label='Validation Accuracy')
 9 plt.legend(loc='lower right')
10 plt.title('Accuracy : Training vs. Validation ')
11 plt.subplot(2, 2, 2)
12 plt.plot(range(30), loss,'bo' ,label='Training Loss')
13 plt.plot(range(30), val_loss, label='Validation Loss')
14 plt.title('Loss : Training vs. Validation ')
15 plt.legend(loc='upper right')
16 plt.show()

 

 9.用ImageDataGenerator數據增強

train_datagen = ImageDataGenerator(rescale=1./255,
                                  rotation_range=40, #將圖像隨機旋轉40度
                                  width_shift_range=0.2, #在水平方向上平移比例為0.2
                                  height_shift_range=0.2, #在垂直方向上平移比例為0.2
                                  shear_range=0.2, #隨機錯切變換的角度為0.2
                                  zoom_range=0.2, #圖片隨機縮放的范圍為0.2
                                  horizontal_flip=True, #隨機將一半圖像水平翻轉
                                  fill_mode='nearest') #填充創建像素

X_val1 = ImageDataGenerator(rescale=1./255) 

X_train1 = train_datagen.flow_from_dataframe(
                        X_train,
                        target_size=(150,150), 
                        batch_size=32, 
                        class_mode='categorical' 
                        )

X_val1= test_datagen.flow_from_dataframe(
                        X_test,
                        target_size=(150,150), 
                        batch_size=32,
                        class_mode='categorical')

再次訓練模型,並繪制繪制損失曲線和精度曲線圖,得到結果圖

 

 

10.導入圖片進行預測

 1 from PIL import Image
 2 def con(file,outdir,w=224,h=224):
 3     img1=Image.open(file)
 4     img2=img1.resize((w,h),Image.BILINEAR)
 5     img2.save(os.path.join(outdir,os.path.basename(file)))
 6 file='D:/python的課程設計/預測/414.jpg'
 7 con(file,'D:/python的課程設計/預測/')
 8 model=load_model('h20')
 9 img_path='D:/python的課程設計/預測/414.jpg'
10 img = load_img(img_path)
11 img = img_to_array(img)
12 img = np.expand_dims(img, axis=0)
13 out = model.predict(img)
14 print(out)
15 dict={'0':'','1':'','2':'','3':'猴子'}
16 for i in range(4):
17     if out[0][i]>0.5:
18         print(dict[str(i)])
19 img=plt.imread('D:/python的課程設計/預測/414.jpg')
20 plt.imshow(img)

 

 

 1 file='D:/python的課程設計/預測/512.jpg'
 2 con(file,'D:/python的課程設計/預測/')
 3 model=load_model('h20')
 4 img_path='D:/python的課程設計/預測/512.jpg'
 5 img = load_img(img_path)
 6 img = img_to_array(img)
 7 img = np.expand_dims(img, axis=0)
 8 out = model.predict(img)
 9 print(out)
10 dict={'0':'','1':'','2':'','3':'猴子'}
11 for i in range(4):
12     if out[0][i]>0.5:
13         print(dict[str(i)])
14 img=plt.imread('D:/python的課程設計/預測/512.jpg')
15 plt.imshow(img)

 

 

 

 1 file='D:/python的課程設計/預測/n3044.jpg'
 2 con(file,'D:/python的課程設計/預測/')
 3 model=load_model('h20')
 4 img_path='D:/python的課程設計/預測/n3044.jpg'
 5 img = load_img(img_path)
 6 img = img_to_array(img)
 7 img = np.expand_dims(img, axis=0)
 8 out = model.predict(img)
 9 print(out)
10 dict={'0':'','1':'','2':'','3':'猴子'}
11 for i in range(4):
12     if out[0][i]>0.5:
13         print(dict[str(i)])
14 img=plt.imread('D:/python的課程設計/預測/n3044.jpg')
15 plt.imshow(img)

 

 

 

 


全部代碼附上:

  1 #導入需要用到的庫
  2 import numpy as np 
  3 import pandas as pd
  4 import os
  5 import tensorflow as tf
  6 import matplotlib.pyplot as plt
  7 from pathlib import Path
  8 from sklearn.model_selection import train_test_split
  9 from keras.models import Sequential
 10 from keras.layers import Activation
 11 from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
 12 from keras.applications.resnet import preprocess_input
 13 from keras_preprocessing.image import ImageDataGenerator
 14 from keras.models import load_model
 15 from keras.preprocessing.image import load_img, img_to_array
 16 from keras import optimizers
 17 
 18 dir = Path('D:/python的課程設計/fire')
 19 
 20 # 用glob遍歷在dir路徑中所有jpg格式的文件,並將所有的文件名添加到filepaths列表中
 21 filepaths = list(dir.glob(r'**/*.jpg'))
 22 
 23 # 將文件中的分好的小文件名(種類名)分離並添加到labels的列表中
 24 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))
 25 
 26 # 將filepaths通過pandas轉換為Series數據類型
 27 filepaths = pd.Series(filepaths, name='FilePaths').astype(str)
 28 
 29 # 將labels通過pandas轉換為Series數據類型
 30 labels = pd.Series(labels, name='Labels').astype(str)
 31 
 32 # 將filepaths和Series兩個Series的數據類型合成DataFrame數據類型
 33 df = pd.merge(filepaths, labels, right_index=True, left_index=True)
 34 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
 35 df = df.sample(frac=1).reset_index(drop=True)
 36 #查看形成的DataFrame的數據
 37 df
 38 #查看圖像以及對應的標簽
 39 fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))
 40 
 41 for i, a in enumerate(ax.flat):
 42     a.imshow(plt.imread(df.FilePaths[i]))
 43     a.set_title(df.Labels[i])
 44     
 45 plt.tight_layout()
 46 plt.show()
 47 
 48 # 由總的數據集生成分別生成訓練集,測試集和驗證集
 49 #將總數據按10:1的比例分配給X_train, X_test
 50 X_train, X_test = train_test_split(df, test_size=0.1, stratify=df['Labels'])
 51 
 52 print('Shape of Train Data: ', X_train.shape)
 53 print('Shape of Test Data: ', X_test.shape)
 54 
 55 # 將總數據按5:1的比例分配給X_train, X_train
 56 X_train, X_val = train_test_split(X_train, test_size=0.2, stratify=X_train['Labels'])
 57 
 58 print('Shape of Train Data: ', X_train.shape)
 59 print('Shape of Val Data: ', X_val.shape)
 60 
 61 # 查看各個標簽的圖片張數
 62 X_train['Labels'].value_counts(ascending=True)
 63 
 64 # 批量大小
 65 BATCH_SIZE = 32
 66 # 輸入圖片的大小
 67 IMG_SIZE = (224, 224)
 68 
 69 # 圖像預處理
 70 img_data_gen = ImageDataGenerator(preprocessing_function=preprocess_input)
 71 
 72 X_train = img_data_gen.flow_from_dataframe(dataframe=X_train,
 73                                           x_col='FilePaths',
 74                                           y_col='Labels',
 75                                           target_size=IMG_SIZE,
 76                                           color_mode='rgb',
 77                                           class_mode='binary',
 78                                           batch_size=BATCH_SIZE,
 79                                           seed=42)
 80 
 81 X_val = img_data_gen.flow_from_dataframe(dataframe=X_val,
 82                                           x_col='FilePaths',
 83                                           y_col='Labels',
 84                                           target_size=IMG_SIZE,
 85                                           color_mode='rgb',
 86                                           class_mode='binary',
 87                                           batch_size=BATCH_SIZE,
 88                                           seed=42)
 89 X_test = img_data_gen.flow_from_dataframe(dataframe=X_test,
 90                                           x_col='FilePaths',
 91                                           y_col='Labels',
 92                                           target_size=IMG_SIZE,
 93                                           color_mode='rgb',
 94                                           class_mode='binary',
 95                                           batch_size=BATCH_SIZE,
 96                                           seed=42)
 97 
 98 #查看經過處理的圖片以及它的binary標簽
 99 fit, ax = plt.subplots(nrows=2, ncols=3, figsize=(13,7))
100 
101 for i, a in enumerate(ax.flat):
102     img, label = X_train.next()
103     a.imshow(img[0],)
104     a.set_title(label[0])
105 
106 plt.tight_layout()
107 plt.show()
108 
109 #構建神經網絡
110 model = Sequential()
111 # 數據歸一化處理
112 model.add(tf.keras.layers.experimental.preprocessing.Rescaling(1./255))
113 
114 # 1.Conv2D層,32個過濾器
115 model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(224, 224, 3)))#圖形是彩色,‘rgb’,所以設置3
116 model.add(Activation('relu'))
117 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
118 
119 # 2.Conv2D層,64個過濾器
120 model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same'))
121 model.add(Activation('relu'))
122 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
123 
124 # 3.Conv2D層,128個過濾器
125 model.add(Conv2D(filters=128, kernel_size=(3,3), padding='same'))
126 model.add(Activation('relu'))
127 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
128 
129 # 將輸入層的數據壓縮成1維數據,全連接層只能處理一維數據
130 model.add(Flatten())
131 
132 # 全連接層
133 model.add(Dense(256))
134 model.add(Activation('relu'))
135 
136 # 減少過擬合
137 model.add(Dropout(0.5))
138 
139 # 全連接層
140 model.add(Dense(1))
141 model.add(Activation('sigmoid'))
142 
143 # 模型編譯
144 model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
145               loss="categorical_crossentropy", 
146               metrics=["accuracy"])
147 #利用批量生成器訓練模型
148 h1 = model.fit(X_train, validation_data=X_val,
149                epochs=30, )
150 #保存模型
151 model.save('t1')
152 
153 #繪制損失曲線和精度曲線圖
154 accuracy = h1.history['accuracy']
155 loss = h1.history['loss']
156 val_loss = h1.history['val_loss']
157 val_accuracy = h1.history['val_accuracy']
158 plt.figure(figsize=(17, 7))
159 plt.subplot(2, 2, 1)
160 plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
161 plt.plot(range(30), val_accuracy, label='Validation Accuracy')
162 plt.legend(loc='lower right')
163 plt.title('Accuracy : Training vs. Validation ')
164 plt.subplot(2, 2, 2)
165 plt.plot(range(30), loss,'bo' ,label='Training Loss')
166 plt.plot(range(30), val_loss, label='Validation Loss')
167 plt.title('Loss : Training vs. Validation ')
168 plt.legend(loc='upper right')
169 plt.show()
170 
171 from PIL import Image
172 def con(file,outdir,w=224,h=224):
173     img1=Image.open(file)
174     img2=img1.resize((w,h),Image.BILINEAR)
175     img2.save(os.path.join(outdir,os.path.basename(file)))
176 file='D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg'
177 con(file,'D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/')
178 model=load_model('t1')
179 img_path='D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg'
180 img = load_img(img_path)
181 img = img_to_array(img)
182 img = np.expand_dims(img, axis=0)
183 out = model.predict(img)
184 if out[0]>0.5:
185         print('是火災的概率為',out[0])
186 else:
187          print('不是火災')
188 img=plt.imread('D:/python的課程設計/NA_Fish_Dataset/Black Sea Sprat/F_23.jpg')
189 plt.imshow(img)
190 
191 dir = Path('D:/python的課程設計1')
192 
193 # 用glob遍歷在dir路徑中所有jpg格式的文件,並將所有的文件名添加到filepaths列表中
194 filepaths = list(dir.glob(r'**/*.jpg'))
195 
196 # 將文件中的分好的小文件名(種類名)分離並添加到labels的列表中
197 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))
198 
199 # 將filepaths通過pandas轉換為Series數據類型
200 filepaths = pd.Series(filepaths, name='FilePaths').astype(str)
201 
202 # 將labels通過pandas轉換為Series數據類型
203 labels = pd.Series(labels, name='Labels').astype(str)
204 
205 # 將filepaths和Series兩個Series的數據類型合成DataFrame數據類型
206 df = pd.merge(filepaths, labels, right_index=True, left_index=True)
207 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
208 df = df.sample(frac=1).reset_index(drop=True)
209 
210 #構建神經網絡
211 model = Sequential()
212 # 數據歸一化處理
213 model.add(tf.keras.layers.experimental.preprocessing.Rescaling(1./255))
214 
215 # 1.Conv2D層,32個過濾器
216 model.add(Conv2D(filters=32, kernel_size=(3,3), padding='same', input_shape=(224, 224, 3)))#圖形是彩色,‘rgb’,所以設置3
217 model.add(Activation('relu'))
218 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
219 
220 # 2.Conv2D層,64個過濾器
221 model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same'))
222 model.add(Activation('relu'))
223 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
224 
225 # 3.Conv2D層,128個過濾器
226 model.add(Conv2D(filters=128, kernel_size=(3,3), padding='same'))
227 model.add(Activation('relu'))
228 model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
229 
230 # 將輸入層的數據壓縮成1維數據,全連接層只能處理一維數據
231 model.add(Flatten())
232 
233 # 全連接層
234 model.add(Dense(256))
235 model.add(Activation('relu'))
236 
237 # 減少過擬合
238 model.add(Dropout(0.5))
239 
240 # 全連接層
241 model.add(Dense(4))#需要識別的有4個種類
242 model.add(Activation('softmax'))#softmax是基於二分類函數sigmoid的多分類函數
243 
244 # 模型編譯
245 model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
246               loss="categorical_crossentropy", 
247               metrics=["accuracy"])
248 #利用批量生成器訓練模型
249 h1 = model.fit(X_train, validation_data=X_val,
250                epochs=30, )
251 #保存模型
252 model.save('h21')
253 
254 
255 #繪制損失曲線和精度曲線圖
256 accuracy = h1.history['accuracy']
257 loss = h1.history['loss']
258 val_loss = h1.history['val_loss']
259 val_accuracy = h1.history['val_accuracy']
260 plt.figure(figsize=(17, 7))
261 plt.subplot(2, 2, 1)
262 plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
263 plt.plot(range(30), val_accuracy, label='Validation Accuracy')
264 plt.legend(loc='lower right')
265 plt.title('Accuracy : Training vs. Validation ')
266 plt.subplot(2, 2, 2)
267 plt.plot(range(30), loss,'bo' ,label='Training Loss')
268 plt.plot(range(30), val_loss, label='Validation Loss')
269 plt.title('Loss : Training vs. Validation ')
270 plt.legend(loc='upper right')
271 plt.show()
272 
273 #定義ImageDataGenerator參數
274 train_datagen = ImageDataGenerator(rescale=1./255,
275                                   rotation_range=40, #將圖像隨機旋轉40度
276                                   width_shift_range=0.2, #在水平方向上平移比例為0.2
277                                   height_shift_range=0.2, #在垂直方向上平移比例為0.2
278                                   shear_range=0.2, #隨機錯切變換的角度為0.2
279                                   zoom_range=0.2, #圖片隨機縮放的范圍為0.2
280                                   horizontal_flip=True, #隨機將一半圖像水平翻轉
281                                   fill_mode='nearest') #填充創建像素
282 
283 X_val1 = ImageDataGenerator(rescale=1./255) 
284 
285 X_train1 = train_datagen.flow_from_dataframe(
286                         X_train,
287                         target_size=(150,150), 
288                         batch_size=32, 
289                         class_mode='categorical' 
290                         )
291 
292 X_val1= test_datagen.flow_from_dataframe(
293                         X_test,
294                         target_size=(150,150), 
295                         batch_size=32,
296                         class_mode='categorical')
297 
298 from PIL import Image
299 def con(file,outdir,w=224,h=224):
300     img1=Image.open(file)
301     img2=img1.resize((w,h),Image.BILINEAR)
302     img2.save(os.path.join(outdir,os.path.basename(file)))
303 file='D:/python的課程設計/預測/414.jpg'
304 con(file,'D:/python的課程設計/預測/')
305 model=load_model('h21')
306 img_path='D:/python的課程設計/預測/414.jpg'
307 img = load_img(img_path)
308 img = img_to_array(img)
309 img = np.expand_dims(img, axis=0)
310 out = model.predict(img)
311 print(out)
312 dict={'0':'','1':'','2':'','3':'猴子'}
313 for i in range(4):
314     if out[0][i]>0.5:
315         print(dict[str(i)])
316 img=plt.imread('D:/python的課程設計/預測/414.jpg')
317 plt.imshow(img)

(四)總結:本次的程序設計主要內容是機器學習的標簽學習,通過本次課程設計,加深了我對機器學習以及其標簽學習的理解。

機器學習就是通過利用數據,訓練模型,然后模型預測的一種方法。這次學習主要是對二分類和多分類進行實踐。二分類:所用到的二分類函數即sigmoid,而多分類用到的則是softmax基於二分類的多分類函數。sigmoid是對每一個輸出值進行非線性化,而sofmax則是計算比重,二者結果相似,都具有歸一作用,但softmax是一個針對輸出結果歸一化的過程sigmoid是則是一個非線性激活過程,即當輸出層為一個神經元時會用sigmoid,softmax一般和one-hot標簽配合使用,一般用於網絡的最后一層,sigmoid與0,1真實標簽配合使用。使用softmax時應將損失函數設置為categorical_crossentropy損失函數,而使用sigmoid時則將損失函數設置為binary_crossentropy損失函數。


本次程序設計的不足:在數據增強上效果不是很明顯,在設計過程中還遇到圖像失真導致訓練精度上升緩慢

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM