-
Notifications
You must be signed in to change notification settings - Fork 0
/
cnn_leaf_clf.py
133 lines (90 loc) · 5.48 KB
/
cnn_leaf_clf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import numpy as np
import pandas as pd
from scipy import ndimage
from scipy import misc
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedShuffleSplit
from matplotlib import pyplot as plt
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
img_dir = 'images/'
n_images = 1584
rows = int(467*0.2)
cols = int(526*0.2)
def encode(train, test):
label_encoder = LabelEncoder().fit(train.species)
labels = label_encoder.transform(train.species)
classes = list(label_encoder.classes_)
train = train.drop(['species', 'id'], axis=1)
test = test.drop('id', axis=1)
return train, labels, test, classes
def load_image_data():
_2d_images=[]
img_data = np.vstack([misc.imresize(arr= ndimage.imread(img_dir+str(i+1)+'.jpg'), size= (rows, cols), interp='bilinear', mode=None).reshape(-1,) for i in range(n_images)])
#_2d_images = np.hstack([misc.imresize(arr= ndimage.imread(img_dir+str(i+1)+'.jpg'), size= (rows, cols), interp='bilinear', mode=None) for i in range(n_images)])
for i in range(n_images):
_2d_images.append(misc.imresize(arr= ndimage.imread(img_dir+str(i+1)+'.jpg'), size= (rows, cols), interp='bilinear', mode=None))
return img_data, np.array(_2d_images)
train, labels, test, classes = encode(train, test)
train = train.values
img_data, _2d_images = load_image_data()
##plt.imshow(_2d_images[0])#, interpolation='nearest')
##plt.show()
#img_data = np.array(img_data)
##img_data = img_data.reshape(1584, rows,cols)
##print("data loaded")
##input()
# splittrain data into train and validation
sss = StratifiedShuffleSplit(test_size=0.2, random_state=23)
for train_index, valid_index in sss.split(train, labels):
X_train, X_valid = train[train_index], train[valid_index]
y_train, y_valid = labels[train_index], labels[valid_index]
X_train_img, X_valid_img = img_data[train_index], img_data[valid_index]
X_train_2dimg, X_valid_2dimg = _2d_images[train_index], _2d_images[valid_index]
X_test = test.values
print("Done")
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D
from keras import backend as K
from keras.callbacks import ReduceLROnPlateau, EarlyStopping
batch_size = 1
num_classes = len(classes)
epochs = 20
img_rows, img_cols = rows, cols #dimensões das imagens
X_train_2dimg = X_train_2dimg.reshape(X_train_2dimg.shape[0], img_rows, img_cols, 1) #ajustando o tamanho da matriz de treino
X_valid_2dimg = X_valid_2dimg.reshape(X_valid_2dimg.shape[0], img_rows, img_cols, 1) #ajustando o tamanho da matriz de teste
input_shape = (img_rows, img_cols, 1) #definindo o tamanho da entrada da rede
X_train_2dimg = X_train_2dimg.astype('float32') #transformando os píxels das imagens em floats
X_valid_2dimg = X_valid_2dimg.astype('float32') #transformando os píxels das imagens em floats
y_train = keras.utils.to_categorical(y_train, num_classes) #convertendo as classes em vetores binários (one hot encoding)
y_valid = keras.utils.to_categorical(y_valid, num_classes)
model = Sequential() #Criando o modelo
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape)) #Camada de convolução 2d, com janela 3x3, e Adcionando a ativação relu.
model.add(Conv2D(64, (3, 3), activation='relu')) #Camada de convolução 2d, com janela 3x3, e Adcionando a ativação relu.
model.add(AveragePooling2D(pool_size=(2, 2))) #Camada de Pooling 2d, de tamanho 2x2, através da média. (Retira a média aritmética de janelas 2x2 na imagem, reduzindo a quantidade de características 4->1 por janela)
model.add(Dropout(0.25)) #Camada de Dropout para evitar overfitting. Nada mais é do que desativar um neurônio. No caso a probabilidade de que isso seja feita é de 0.25, no exemplo em questão.
model.add(Flatten()) #Reduz a dimensão da camada. output_shape == (None, 64, 32, 32) -> Flatten() -> output_shape == (None, 65536)
model.add(Dense(128, activation='relu')) #Camada completamente conectada
model.add(Dense(num_classes, activation='softmax')) #Camada de saída, com ativação softmax.
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# monitores para o treinamento da rede
#https://keras.io/callbacks/
#Reduz a taxa de aprendizado
reduce_lr = ReduceLROnPlateau(monitor='val_loss', #observar a função de perda no conjunto de validação
factor=0.2, #fator pela qual a taxa será reduzida -> nova_taxa = taxa_atual * factor
verbose=1,
patience=1, # número de épocas, sem redução na função de perda, que o monitor espera para agir.
min_lr=0.0001) #limite inferior da nova_taxa. Menor que isso e o monitor não irá reduzir mais a taxa.
#Interrompe o treinamento
early_stopping=EarlyStopping(monitor='val_loss', #observar a função de perda no conjunto de validação
patience=4, # número de épocas, sem redução na função de perda, que o monitor espera para agir.
verbose=1,)
#fazendo uso dos monitores criados
model.fit(X_train_2dimg, y_train, batch_size=batch_size, epochs=epochs, callbacks=[reduce_lr, early_stopping], verbose=1, validation_data=(X_valid_2dimg, y_valid))
loss, accuracy = model.evaluate(X_valid_2dimg, y_valid, verbose=0)
print('Test accuracy:', accuracy)
p = model.predict(X_valid_2dimg)