В предыдущей серии я пытался сделать из мухи разумное существо. Коротко — не вышло. Муха упорно не хотела учиться.
Мухой была маленькая простая нейронная сеть, основанная на умножении матриц, сигмоиде и обратном распространении ошибки. Её учение состояло в распознавании фотографий с цветами.
Напомню, что внутри две сети — первая анализирует кусочки исходного изображения, а вторая работает с матрицей, сложенной из результатов работы первой сетки.
Обучение проходило кое-как, результата не было. Затем, оставив попытки обучения по уважительным причинам (как то — вечер субботы, ночь и утро воскресенья), я все же думал, что делать дальше. Какие-то возможные решения были намечены в конце первой статьи, с них и продолжил.
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
nn2 = NN([middleShape, (40, middleShape[0]), (y.shape[1], 40), y.shape])
minFails = None
lastSyns = None
for epoch in range(100):
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
# цикл обучения
for f in fl:
i = readImage(f, imageSize)
nn.learn(i, yy, 2)
mid = nn.calc(i)
nn2.learn(mid, y, 1000)
nextSyns=None
fails = 0
failFiles = []
# цикл проверки результата
for f in all:
i = readImage(f, imageSize)
mid = nn.calc(i)
res = nn2.calc(mid)
delta = (y-res)
v = round(np.std(delta),3)
if v > 0.2 and f in fl: # неправильно - цветок отнесен к не-цветкам
fails += 1
failFiles.append(f)
elif v<0.2 and f in nofl: # неправильно - не-цветок отнесен к цветкам
fails +=1
failFiles.append(f)
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
if not (lastSyns is None):
nn.net.syns = lastSyns
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
# цикл обучения
# цикл проверки результата
if minFails == None or fails < minFails:
minFails = fails
lastSyns = nn.net.syns
Epoch = 25
flowers\178.jpg res = [[ 0.64 0.89 0.65 0.87]] v = 0.619
flowers\179.jpg res = [[ 0.91 0.2 0.96 0.15]] v = 0.12
flowers\180.jpg res = [[ 0.95 0.1 0.95 0.1 ]] v = 0.074
flowers\182.jpg res = [[ 1. 0. 1. 0.]] v = 0.0
flowers\186-2.jpg res = [[ 0.98 0.05 0.98 0.04]] v = 0.032
flowers\186.jpg res = [[ 0.99 0.01 0.99 0.01]] v = 0.01
flowers\187.jpg res = [[ 0.83 0.48 0.81 0.5 ]] v = 0.335
flowers\190 (2).jpg res = [[ 1. 0. 1. 0.]] v = 0.001
flowers\190.jpg res = [[ 0.96 0.06 0.96 0.05]] v = 0.045
flowers\191.jpg res = [[ 0.97 0.01 0.96 0.01]] v = 0.022
flowers\195.jpg res = [[ 1. 0. 1. 0.]] v = 0.004
flowers\199.jpg res = [[ 0.91 0.16 0.9 0.16]] v = 0.127
flowers\2.jpg res = [[ 0.99 0.01 0.99 0.01]] v = 0.009
flowers\200.jpg res = [[ 0.99 0.01 1. 0.01]] v = 0.009
noflowers\032.jpg res = [[ 0.71 0.73 0.79 0.73]] v = 0.49
noflowers\085.jpg res = [[ 0.87 0.29 0.85 0.32]] v = 0.222
noflowers\088.jpg res = [[ 0.92 0.22 0.94 0.24]] v = 0.15
noflowers\122.JPG res = [[ 0.72 0.68 0.73 0.68]] v = 0.479
noflowers\123.jpg res = [[ 0.74 0.54 0.69 0.6 ]] v = 0.427
noflowers\173.jpg res = [[ 0.43 0.9 0.57 0.9 ]] v = 0.702
noflowers\202.jpg res = [[ 0.99 0. 0.98 0. ]] v = 0.008
noflowers\205.jpg res = [[ 0.34 0.92 0.57 0.81]] v = 0.711
noflowers\cutxml.jpg res = [[ 0.79 0.41 0.79 0.41]] v = 0.309
noflowers\Getaway.jpg res = [[ 0.75 0.65 0.76 0.65]] v = 0.449
noflowers\IMGP1800.JPG res = [[ 0.81 0.55 0.81 0.55]] v = 0.367
noflowers\trq-4.png res = [[ 0.52 0.81 0.54 0.83]] v = 0.644
dy = 1.407 dn = 4.958
fails = 4 ['flowers\\178.jpg', 'flowers\\187.jpg', 'noflowers\\088.jpg', 'noflowers\\202.jpg']
min = 4
yy = np.zeros(middleShape)
np.fill_diagonal(yy,1)
yy = np.zeros(middleShape)
np.fill_diagonal(yy,1)
minFails = None
lastYY = yy
nextYY = yy
...
for epoch in range(100):
...
for f in fl:
i = readImage(f, imageSize)
nn.learn(i, nextYY, 2)
mid = nn.calc(i)
nn2.learn(mid, y, 1000)
...
for f in all:
i = readImage(f, imageSize)
mid = nn.calc(i)
res = nn2.calc(mid)
...
if minFails == None or fails < minFails:
minFails = fails
lastYY = nextYY
else:
nextYY = lastYY +(np.random.random(yy.shape)-0.5)/10
Epoch = 79
flowers\178.jpg res = [[ 0.5 0.13 0.52 0.12]] v = 0.309
flowers\179.jpg res = [[ 0.74 0.06 0.75 0.06]] v = 0.16
flowers\180.jpg res = [[ 0.76 0.07 0.75 0.07]] v = 0.155
flowers\182.jpg res = [[ 0.95 0.03 0.94 0.03]] v = 0.044
flowers\186-2.jpg res = [[ 0.7 0.1 0.71 0.09]] v = 0.193
flowers\186.jpg res = [[ 0.61 0.22 0.6 0.2 ]] v = 0.303
flowers\187.jpg res = [[ 0.45 0.13 0.45 0.13]] v = 0.341
flowers\190 (2).jpg res = [[ 0.84 0. 0.67 0.01]] v = 0.14
flowers\190.jpg res = [[ 0.96 0.06 0.94 0.08]] v = 0.061
flowers\191.jpg res = [[ 0.73 0.13 0.72 0.1 ]] v = 0.194
flowers\195.jpg res = [[ 0.85 0.03 0.88 0.03]] v = 0.08
flowers\199.jpg res = [[ 0.83 0.05 0.84 0.04]] v = 0.102
flowers\2.jpg res = [[ 0.81 0.06 0.81 0.06]] v = 0.125
flowers\200.jpg res = [[ 0.92 0.05 0.93 0.04]] v = 0.057
noflowers\032.jpg res = [[ 0.27 0.12 0.3 0.1 ]] v = 0.416
noflowers\085.jpg res = [[ 0.41 0.14 0.41 0.14]] v = 0.365
noflowers\088.jpg res = [[ 0.37 0.15 0.32 0.15]] v = 0.402
noflowers\122.JPG res = [[ 0.4 0.15 0.4 0.14]] v = 0.373
noflowers\123.jpg res = [[ 0.35 0.14 0.33 0.15]] v = 0.401
noflowers\173.jpg res = [[ 0.33 0.17 0.34 0.17]] v = 0.418
noflowers\202.jpg res = [[ 0.44 0.14 0.45 0.12]] v = 0.342
noflowers\205.jpg res = [[ 0.63 0.06 0.74 0.07]] v = 0.192
noflowers\cutxml.jpg res = [[ 0.52 0.13 0.45 0.13]] v = 0.323
noflowers\Getaway.jpg res = [[ 0.38 0.15 0.38 0.15]] v = 0.386
noflowers\IMGP1800.JPG res = [[ 0.4 0.15 0.4 0.14]] v = 0.371
noflowers\trq-4.png res = [[ 0.19 0.21 0.17 0.28]] v = 0.533
dy = 2.264 dn = 4.522
fails = 4 ['flowers\\178.jpg', 'flowers\\186.jpg', 'flowers\\187.jpg', 'noflowers\\205.jpg']
min = 4
for epoch in range(100):
print('Epoch =', epoch)
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
if not (lastSyns is None):
nextSyns = lastSyns
for r in range(len(nextSyns)):
rand = (np.random.random(nextSyns[r].shape)-0.5)/20
nextSyns[r] = nextSyns[r] + rand
nn.net.syns = nextSyns
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
for f in fl:
i = readImage(f, imageSize)
nn.learn(i, nextYY, 2)
mid = nn.calc(i)
nn2.learn(mid, y, 1000)
...
if minFails == None or fails < minFails:
minFails = fails
lastSyns = nn.net.syns
lastYY = nextYY
else:
nextYY = lastYY +(np.random.random(yy.shape)-0.5)/20
Epoch = 38
flowers\178.jpg res = [[ 0.91 0.26 0.91 0.25]] v = 0.174
flowers\179.jpg res = [[ 0.99 0. 0.99 0. ]] v = 0.005
flowers\180.jpg res = [[ 0.9 0.21 0.89 0.2 ]] v = 0.153
flowers\182.jpg res = [[ 1. 0. 1. 0.]] v = 0.0
flowers\186-2.jpg res = [[ 1. 0.01 0.99 0.01]] v = 0.008
flowers\186.jpg res = [[ 0.91 0.12 0.93 0.07]] v = 0.09
flowers\187.jpg res = [[ 0.83 0.43 0.83 0.44]] v = 0.303
flowers\190 (2).jpg res = [[ 1. 0. 1. 0.]] v = 0.0
flowers\190.jpg res = [[ 1. 0. 1. 0.]] v = 0.001
flowers\191.jpg res = [[ 1. 0. 1. 0.]] v = 0.0
flowers\195.jpg res = [[ 0.99 0. 1. 0. ]] v = 0.004
flowers\199.jpg res = [[ 0.97 0.03 0.98 0.03]] v = 0.029
flowers\2.jpg res = [[ 1. 0. 1. 0.]] v = 0.003
flowers\200.jpg res = [[ 1. 0. 1. 0.]] v = 0.0
noflowers\032.jpg res = [[ 0.88 0.55 0.8 0.67]] v = 0.389
noflowers\085.jpg res = [[ 0.25 0.96 0.27 0.96]] v = 0.848
noflowers\088.jpg res = [[ 0.84 0.42 0.79 0.37]] v = 0.29
noflowers\122.JPG res = [[ 0.68 0.66 0.69 0.66]] v = 0.49
noflowers\123.jpg res = [[ 0.74 0.63 0.71 0.6 ]] v = 0.445
noflowers\173.jpg res = [[ 0.86 0.46 0.76 0.52]] v = 0.343
noflowers\202.jpg res = [[ 0.22 0.92 0.44 0.95]] v = 0.808
noflowers\205.jpg res = [[ 0.8 0.82 0.71 0.88]] v = 0.547
noflowers\cutxml.jpg res = [[ 0.99 0.03 0.97 0.02]] v = 0.022
noflowers\Getaway.jpg res = [[ 0.7 0.65 0.7 0.65]] v = 0.474
noflowers\IMGP1800.JPG res = [[ 0.79 0.5 0.77 0.5 ]] v = 0.36
noflowers\trq-4.png res = [[ 0.77 0.21 0.69 0.07]] v = 0.215
dy = 0.77 dn = 5.231
fails = 2 ['flowers\\187.jpg', 'noflowers\\cutxml.jpg']
min = 2
for i in range(len(lastSyns)):
np.savetxt('syns_save%s.txt'%i, lastSyns[i])
for i in range(len(lastSyns2)):
np.savetxt('syns2_save%s.txt'%i, lastSyns2[i])
StartLearn = False
if not StartLearn:
pictDir = 'C:\\AllPictures'
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
nn.net.syns[0] = np.loadtxt('syns_save0.txt',ndmin=nn.net.syns[0].ndim)
nn.net.syns[1] = np.loadtxt('syns_save1.txt',ndmin=nn.net.syns[1].ndim)
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
nn2.syns[0] = np.loadtxt('syns2_save0.txt',ndmin=nn2.syns[0].ndim)
nn2.syns[1] = np.loadtxt('syns2_save1.txt',ndmin=nn2.syns[1].ndim)
files = [e.path for e in os.scandir(pictDir)]
for f in files:
i = readImage(f, imageSize)
mid = nn.calc(i)
res = nn2.calc(mid)
delta = y-res
v = round(np.std(delta),3)
if v <= 0.3:
print('Flower',f,v)
## else:
## print('No flower',f, v)
import numpy as np
from nnmat import *
import os
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import meshandler
import random
import cv2
class ImgNN:
def __init__(self, shape, resultShape = (16, 16), imageSize = (400,400)):
self.resultShape = resultShape
self.w = imageSize[0] // shape[0]
self.h = imageSize[1] // shape[1]
self.net = NN([shape, (1,shape[0]), (1,1)])
self.shape = shape
self.imageSize = imageSize
def learn(self, srcArr, result, cycles):
for c in range(cycles):
for x in range(self.w):
for y in range(self.h):
a = srcArr[x:x+self.shape[0], y:y+self.shape[1]]
if a.shape != (self.shape[0], self.shape[1]):
print(a.shape)
continue
self.net.learn(a, result[x,y], 1)
def calc(self, srcArr):
resArr = np.zeros(self.resultShape)
for x in range(self.w):
for y in range(self.h):
a = srcArr[x:x+self.shape[0], y:y+self.shape[1]]
if a.shape != (self.shape[0], self.shape[1]):
continue
if x >= self.resultShape[0] or y >= self.resultShape[1]:
continue
res = self.net.calc(a)
resArr[x,y] = res[0,0]
return resArr
def learnFile(self, file, result, cycles):
return self.learn(readImage(file, self.imageSize), result, cycles)
def calcFile(self, file):
return self.calc(readImage(file, self.imageSize))
def readImageCV(file, imageSize):
img = cv2.imread(file)
small = cv2.resize(img, imageSize)
hsv = cv2.cvtColor(small, cv2.COLOR_BGR2HSV)
return hsv[:,:,0]/255
def readImageQ(file, imageSize):
img = QImage(file)
if img.isNull():
return 0
img = img.convertToFormat(QImage.Format_Grayscale8)
img = img.scaled(imageSize[0],imageSize[1],Qt.IgnoreAspectRatio)
srcBi = img.bits()
srcBi.setsize(img.width() * img.height())
srcBy = bytes(srcBi)
srcW, srcH = img.width(), img.height()
srcArr = np.recarray((srcH, srcW), dtype=np.uint8, buf=srcBy).view(dtype=np.uint8,type=np.ndarray)
return srcArr/255
def readImageCVQ(file, imageSize):
img = QImage(file)
if img.isNull():
return 0
img = img.convertToFormat(QImage.Format_RGB888)
img = img.scaled(imageSize[0],imageSize[1],Qt.IgnoreAspectRatio)
srcBi = img.bits()
srcBi.setsize(img.byteCount())
srcBy = bytes(srcBi)
srcW, srcH = img.width(), img.height()
bp = img.depth() // 8
srcArr = np.recarray((srcH, srcW, bp), dtype=np.uint8, buf=srcBy)
srcArr = srcArr.view(dtype=np.uint8,type=np.ndarray)
hsv = cv2.cvtColor(srcArr, cv2.COLOR_RGB2HSV)
return hsv[:,:,0]/255
if __name__ == '__main__':
readImage = readImageCVQ
y = np.array([[1,0,1,0]])
firstShape = (40, 40)
middleShape = (10, 10)
imageSize = firstShape[0]*middleShape[0], firstShape[1]*middleShape[1]
StartLearn = False
if not StartLearn:
pictDir = 'C:\\AllPictures'
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
nn.net.syns[0] = np.loadtxt('syns_save0.txt',ndmin=nn.net.syns[0].ndim)
nn.net.syns[1] = np.loadtxt('syns_save1.txt',ndmin=nn.net.syns[1].ndim)
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
nn2.syns[0] = np.loadtxt('syns2_save0.txt',ndmin=nn2.syns[0].ndim)
nn2.syns[1] = np.loadtxt('syns2_save1.txt',ndmin=nn2.syns[1].ndim)
files = [e.path for e in os.scandir(pictDir)]
for f in files:
i = readImage(f, imageSize)
mid = nn.calc(i)
res = nn2.calc(mid)
delta = y-res
v = round(np.std(delta),3)
if v <= 0.3:
print('Flower',f,v)
## else:
## print('No flower',f, v)
else:
fl = [e.path for e in os.scandir('flowers')]
nofl = [e.path for e in os.scandir('noflowers')]
all = fl+nofl
yy = np.zeros(middleShape)
np.fill_diagonal(yy,1)
minFails = None
lastSyns = None
nextSyns = None
lastSyns2 = None
lastYY = yy
nextYY = yy
minDy = None
maxDn = None
for epoch in range(100):
print('Epoch =', epoch)
nn = ImgNN(firstShape, resultShape=middleShape, imageSize=imageSize)
if not (lastSyns is None):
nextSyns = lastSyns
for r in range(len(nextSyns)):
rand = (np.random.random(nextSyns[r].shape)-0.5)/20
nextSyns[r] = nextSyns[r] + rand
nn.net.syns = nextSyns
nn2 = NN([middleShape, (y.shape[1], middleShape[0]), y.shape])
for f in fl:
i = readImage(f, imageSize)
nn.learn(i, nextYY, 2)
## nn.learn(i, yy, 2)
mid = nn.calc(i)
nn2.learn(mid, y, 1000)
nextSyns=None
fails = 0
failFiles = []
dy = 0.0
dn = 0.0
for f in all:
i = readImage(f, imageSize)
mid = nn.calc(i)
res = nn2.calc(mid)
delta = (y-res)
v = round(np.std(delta),3)
#v = round(delta.sum(),3)
print(f, 'res = ', res.round(2),'v =',v)
if f in fl:
dy += v
if f in nofl:
dn += v
if v > 0.2 and f in fl:
fails += 1
failFiles.append(f)
elif v<0.2 and f in nofl:
fails +=1
failFiles.append(f)
print('dy =',dy,'dn =',dn)
if minDy == None or dy < minDy:
minDy = dy
if maxDn == None or dn > maxDn:
maxDn = dn
if minFails == None or fails < minFails:
minFails = fails
lastSyns = nn.net.syns
lastSyns2 = nn2.syns
lastYY = nextYY
else:
nextYY = lastYY +(np.random.random(yy.shape)-0.5)/20
print('fails =',fails, failFiles)
print('min =',minFails)
if minFails <= 1:
print('found!')
break
for i in range(len(lastSyns)):
np.savetxt('syns_save%s.txt'%i, lastSyns[i])
for i in range(len(lastSyns2)):
np.savetxt('syns2_save%s.txt'%i, lastSyns2[i])
def readImageCVQ(file, imageSize):
img = QImage(file)
if img.isNull():
return 0
img = img.convertToFormat(QImage.Format_RGB888)
img = img.scaled(imageSize[0],imageSize[1],Qt.IgnoreAspectRatio)
srcBi = img.bits()
srcBi.setsize(img.byteCount())
srcBy = bytes(srcBi)
srcW, srcH = img.width(), img.height()
bp = img.depth() // 8
srcArr = np.recarray((srcH, srcW, bp), dtype=np.uint8, buf=srcBy)
srcArr = srcArr.view(dtype=np.uint8,type=np.ndarray)
hsv = cv2.cvtColor(srcArr, cv2.COLOR_RGB2HSV)
return hsv[:,:,0]/255
...
readImage = readImageCVQ
К сожалению, не доступен сервер mySQL