Page 14 - Revista_60.pub
P. 14
A PROGRAMAR
ATRAVÉS DOS OLHOS DE UMA REDE NEURONAL
Procede-se à leitura destas, utilizando uma técnica de gens simples e sem ruído. Num exemplo mais realista, o
gerar novas imagens a partir das existentes (aplicando trans- treino da rede terá de ser muito mais longo recorrer a um
formações aleatórias: distorção, rotação, zoom, etc.), para dataset de imagens muito mais completo.
compensar a quantidade relativamente reduzida do dataset de Por facilidade, gravamos a rede treinada (estrutura e
imagens. Obviamente, quantas mais imagens utilizarmos para
treinar o modelo melhor. pesos), para que a possamos utilizar novamente mais tarde
já treinada.
No final obtemos a lista das 6 classes a classificar, no caso
extraída do training set. cnn.fit_generator(
train, steps_per_epoch = 2048, epochs = 4,
validation_data = test, validation_steps = 512)
trainImgs = ImageDataGenerator(
rescale = 1./255, shear_range = 0.2, cnn.save('cnn-fruit.h5')
zoom_range = 0.2, horizontal_flip = True)
testImgs = ImageDataGenerator(rescale = 1./255)
Carregamos a rede já treinada anteriormente e pedi-
train = trainImgs.flow_from_directory( mos que esta identifique as peças presentes nas imagens.
path + '/train', target_size = (imgW, imgH),
batch_size = 16, class_mode = cnn = load_model('cnn-fruit.h5')
'categorical')
test = testImgs.flow_from_directory( for i in range(0, 12):
path + '/test', target_size = (imgW, imgH), file = path + '/unknown-' + str(i) + '.jpg'
batch_size = 16, class_mode = img = image.load_img(
'categorical') file, target_size = (imgW, imgH))
y = cnn.predict(expand_dims(
classes = list(train.class_indices.keys()) image.img_to_array(img), axis = 0))
print('Fruit in:', file, ':', classes[argmax
A partir daqui criamos a CNN, com duas convolution (y)])
layers, onde aplicamos 32 filtros à primeira convolution e 64
filtros à segunda. No final do varrimento dos filtros é aplicada a
ReLU, e de seguida o max pooling.
Após a conclusão das duas convolutions, é efetuado o
flatten.
cnn = Sequential()
cnn.add(Conv2D(
32, kernel, input_shape = (imgW, imgH, 3),
activation = 'relu'))
cnn.add(MaxPooling2D(
pool_size = (downscale, downscale)))
cnn.add(Conv2D(
64, kernel, activation = 'relu'))
cnn.add(MaxPooling2D(
pool_size = (downscale, downscale)))
cnn.add(Flatten())
Neste passo é gerado o vetor de entrada para a rede Fruit in: dataset/unknown-0.jpg : apple
neuronal, que dispõe de uma hidden layer de 128 neurónios Fruit in: dataset/unknown-1.jpg : orange
Fruit in: dataset/unknown-2.jpg : banana
ativados novamente por uma ReLU, e que utiliza o Adam opti- Fruit in: dataset/unknown-3.jpg : pineapple
mizer para aplicação do stochastic gradient descent, e a cate- Fruit in: dataset/unknown-4.jpg : strawberry
gorical cross entropy como função de erro (loss). Fruit in: dataset/unknown-5.jpg : lime
Para testar ainda melhor o modelo vamos pedir que
A camada de saída é constituída por 6 neurónios, cada este identifique 3 outras categorias de maçãs diferentes da-
um correspondente a uma das 6 classificações possíveis, ati- quela usada no treino. Mesmo tendo um padrão de cor e
vada por uma softmax.
textura diferentes, a rede deverá ser capaz de perceber que
ainda assim se tratam de maçãs. Da mesma forma também
cnn.add(Dense(
units = 128, activation = 'relu')) somos capazes de perceber quando vemos uma maçã de
cnn.add(Dense( uma categoria menos habitual, que ainda assim que se trata
units = len(classes), activation = 'softmax')) de uma maçã, porque reconhecemos vários padrões comuns
cnn.compile(
optimizer = 'adam', das maçãs.
loss = 'categorical_crossentropy',
metrics = ['accuracy']) Este teste é muito interessante uma vez que, em caso
de sucesso, deixamos de ter um algoritmo que executa estri-
tamente as funções para o qual foi programado, e passamos
Por fim executamos o processo de treino da rede, sobre a ter um algoritmo que efetua deduções corretas a partir de
o training set e test set, utilizando apenas 4 epochs de 2048 uma aprendizagem.
passos, o que é viável neste exemplo porque se tratam de ima-
14