Hi. I can not figure out how to freeze weights or reset them. When i run my model after training i get 80-90% accuracy but if i load it and run it again it is behaving completely false. Here is my code, thanks for assistance!
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 14 19:35:44 2020
@author: e14
"""
import torch
import torchvision #Bilder vorfabrizieren, library
from torchvision import transforms
from PIL import Image #Bildverarbeitungs library (pil = pillow)
from os import listdir
from os import sys
import random
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn #neural network
import numpy as np
import argparse #Eingagnsargumente
import os.path
from os import path
from torchvision import models
torch.manual_seed(43)
torch.set_deterministic(True)
#Hier schreiben wir unsere Eingagsargumente
parser = argparse.ArgumentParser()
parser.add_argument('--model', help='model MODEL', required=True)
parser.add_argument('--imagesdir', help='imagesdir IMAGESDIR')
parser.add_argument('--epochs', help='epochs EPOCHS', default=30)
parser.add_argument('--timagesdir', help='timagesdir TIMAGESDIR')
args = parser.parse_args()
if ((path.exists(args.model) == False) & (args.imagesdir == None)): #Fehler versicherung
print("Error: Training images not loaded!")
sys.exit()
if ((path.exists(args.model) == True) & (args.timagesdir == None)): #Fehler versicherung
print("Error: Testing images not loaded!")
sys.exit()
normalize = transforms.Normalize(mean=[0.5], std=[0.5]) #grayscale transform
transform=transforms.Compose([
transforms.Resize(256), #Bilder auf derselben Größe
transforms.ToTensor(), #Bilder als Tensoren speichern
normalize]) #selbe Helligkeit,...
#TARGET: HatRiss, HatkeinenRiss
train_data_list=[]
target_list = [] #damit wir labels anfügen können
train_data=[] #wird zu einer liste aus batches
files = listdir(args.imagesdir) #hier habe ich anfangs den Fehler gemacht, das zip-file nicht zu entpacken, daher hat es den Pfad nicht erkannt
if path.exists(args.model) is False:
for idx, i in enumerate(range(len(listdir(args.imagesdir))), start=1): # liefert mir Liste mit allen Dateinamen zurück
f = random.choice(files) # liefert zufälliges element aus der files liste -- wenn wir nur das haben, kann es passieren, dass wir immer dasselbe Element bekommen. Darum:
files.remove(f) # müssen f aus den files removen, nachdem es schon gewählt wurde
img = Image.open(args.imagesdir + "/" + f).convert('RGB') # wir öffnen Bildern und speichern als arrays
img = transforms.functional.to_grayscale(img) #Grayscale wegen RAM
img_tensor = transform(img)
train_data_list.append(img_tensor)
HatRiss = 1 if 'Riss' in f else 0
HatkeinenRiss = 1 if 'KeinRiss' in f else 0
target = [HatRiss, HatkeinenRiss] #soll dann der Output/das Target sein.
target_list.append(target) #Wie sieht der output später von unserem Neuronalen Netzwerk aus?
print("Image " + str(idx) + " out of " + str(len(listdir(args.imagesdir))) + " loaded!")
if len(train_data_list) >= len(listdir(args.imagesdir)) :
print("Appending data to a single list...")
train_data.append((torch.stack(train_data_list), target_list)) # =(Trainingsdaten, Liste) das hier ist ein batch, da sind Bilder mit Lösungen drinnen. Es gibt mehrere batches zu je 55 Bildern)
train_data_list = [] #das brauchen wir nicht mehr, jetzt haben wir mehr RAM verfügbar
print("Appending finished!")
#wollen unser Netz hier schreiben, weil wir unser Netz ja auch brauchen für den Trainingsalgorithmis:
class Flatten(nn.Module):
def forward(self, input):
return input.view(input.size(0), -1)
class Netz(nn.Module):
def __init__(self):
super(Netz, self).__init__()
self.conv1 = nn.Conv2d(1, 2, kernel_size=5) #(wir haben 3 input chanel, output chanel setzen wir auf 10) da wir mit Bilder arbeiten kommt eine convolutional Schicht rein, gleich als erstes
self.conv2 = nn.Conv2d(2, 4, kernel_size=5) #normalerweise macht man gleich mehrere convolutional Schichten
self.conv3 = nn.Conv2d(4, 8, kernel_size=5) #mit den Zahlen kann man am Ende noch ein bisschen herumspielen
self.fc1 = nn.Linear(7616, 1000)
#fully connected layer soll als input genau die Anzahl an Neuronen haben, die torch.Size(, ., ., .) => . mal . mal . ausspuckt
self.fc2 = nn.Linear(1000, 2)
def forward(self, x): #gehen davon aus, dass irgendetwas kaputt gehen wird
x = self.conv1(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = self.conv2(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = self.conv3(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = x.view(-1, 7616) #-1, da der erste Wert, also die batch size, uns nicht interessiert
x = F.relu(self.fc1(x)) # als Aktivierungslayer für unser erstes fully connected layer
x = F.dropout(x)
x = self.fc2(x)
return F.softmax(x, dim=1)
#jetzt müssen wir in unseren fully connected layer umsteigen, aber wir wissen ja nicht, wie unsere Daten in dem Fall jetzt aussehen
exit()
#jetzt generiere ich mein model als neues Netz
model = Netz()
optimizer = optim.RMSprop(model.parameters(), lr = 0.001) #Learning rate
def train(epoch): #model existiert zwar noch nicht, aber wir erschaffen uns unser eigenes model
model.train() #model auf train setzen, damit es auch wirklich trainiert wird und nicht nur ausgeführt
for idx, (data, target) in enumerate(train_data): # Daten aus vorgefertigten Daten beziehen, wir brauchen hier die train data
target = torch.Tensor(target)
data = Variable(data)
target = Variable(target) # müssen data und target ja immer noch als Variablen verarbeiten
optimizer.zero_grad() #setzen unseren Gradienten auf 0, damit wir überhaupt etwas lernen können
out = model(data) #output soll das model data sein
criterion = F.binary_cross_entropy #wollen ja Bilder klassifizieren in zwei Klassen
loss = criterion(out, target) #wollen unser Loss als criterion von output und target berechnen -- zu beachten: target hat zwei Elemente und am Ende soll unser output auch zwei Elemente haben
loss.backward() # wollen unseren Loss back - propagaten
optimizer.step() # wollen unseren Optimizer sagen, dass er etwas tun soll
# das war es mit unserem Trainingsalgorithmus
epoch_num = range(0,int(args.epochs))
if path.exists(args.model) == False: #wir schauen ob unsere Model schon trainiert ist
for idx, epoch in enumerate(epoch_num, start=1): #wollen 30 epcohen lang trainieren
print("Epoch " + str(idx) + " out of " + str(max(epoch_num)+1) + " started!")
train(epoch)
print("Epoch " + str(idx) + " out of " + str(max(epoch_num)+1) + " finished!")
torch.save(model, args.model) #wir speichern unsere trainierte Model
else:
model = torch.load(args.model)
model.eval()
if args.timagesdir is None: sys.exit() #wir prüfen ob wir Model nützen wollen
else:
for i in listdir(args.timagesdir):
test_img = Image.open(args.timagesdir + "/" + i) #wir öffnen die Bildern
test_img = transforms.functional.to_grayscale(test_img) #Grayscale wegen RAM
test_img_tensor = transform(test_img) #wir formattieren die Bildern im richtigen Format
loading_image = model(test_img_tensor[None, ...]) #wir schicken es zu unsere Model
cpu_pred = loading_image.cpu() #wir schicken model mit daten zu Prozessor
numpyresult = cpu_pred.data.numpy() #formattieren im array
listresult = np.ndarray.tolist(numpyresult[0]) #formattieren weiter
endresult = str(listresult).split(", ") #formattieren weiter
bad = endresult[0].replace("[", "") #wir definieren Ausgangswerte
good = endresult[1].replace("]", "") #wir definieren Ausgangswerte
if good > bad: print(i + " is a good cookie.") #Wir definieren Ergebnis
else: print(i + " is a bad cookie.") #Wir definieren Ergebnis