CNN to play Need for Speed

username: sharjeel
cooked: <p>I have been trying to write a code that would play need for speed but it keeps giving me just one type of output every time no matter what the input is given.<br>
Here is the function that records the screen and the keys i use to play the game to create a training data.<br>
def screen_record():</p>
<pre><code>for i in list(range(5))[::-1]:
    print(i+1)
    time.sleep(1)   

last_time = time.time()
print(last_time)

while(True):
    screen = np.array(ImageGrab.grab(bbox=(0,40,800,640)))
    screen = cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY)
    screen = cv2.resize(screen, (100,100))
    keys = key_check()
    output = keys_to_output(keys)
    print(output)
    training_data.append([np.array(screen), output])
    
    #print("loop took {} seconds".format(time.time()-last_time))
    last_time = time.time()
    
    if len(training_data) % 500 == 0:
        print(len(training_data))
        np.random.shuffle(training_data)
        np.save(file_name, training_data)
    
    cv2.imshow("Window", screen)
    
    if cv2.waitKey(1) == ord('q'):
        break
</code></pre>
<p>and here is the CNN model that i have trained.<br>
class CNN(nn.Module):<br>
def <strong>init</strong>(self):<br>
super(CNN, self).<strong>init</strong>()<br>
self.feature_extraction = nn.Sequential(<br>
nn.Conv2d(1, 32, 5),<br>
nn.ReLU(),<br>
nn.Conv2d(32, 64, 5),<br>
nn.ReLU(),<br>
nn.Conv2d(64, 64, 5),<br>
nn.ReLU(),<br>
nn.MaxPool2d(kernel_size=2, stride=2),<br>
nn.Conv2d(64, 64, 5),<br>
nn.ReLU(),<br>
nn.Conv2d(64, 128, 5),<br>
nn.ReLU(),<br>
nn.MaxPool2d(kernel_size=2, stride=2),<br>
)<br>
self.linear_layers = nn.Sequential(<br>
nn.Linear(128<em>18</em>18, 1200),<br>
nn.ReLU(),<br>
nn.Dropout(p=0.5),<br>
nn.Linear(1200, 1200),<br>
nn.ReLU(),<br>
nn.Linear(1200, 120),<br>
nn.ReLU(),<br>
nn.Dropout(p=0.5),<br>
nn.Linear(120, 5),<br>
nn.Sigmoid()<br>
)</p>
<pre><code>def forward(self, image):
    x = self.feature_extraction(image)
    x = x.reshape(-1, 128*18*18)
    x = self.linear_layers(x)
    return x
</code></pre>
<p>model = CNN()<br>
print(model)</p>
<p>if training is True:</p>
<pre><code>training_data = np.load("training_data_02.npy", allow_pickle=True)
np.random.shuffle(training_data)
print(len(training_data))

X = torch.Tensor([i[0] for i in training_data]).view(-1,1,100,100)
Y = torch.Tensor([i[1] for i in training_data])

optimizer = optim.Adam(model.parameters(), lr=0.001)
loss_function = nn.MSELoss()

batch_size = 20
epochs = 5

model.train()

for epoch in tqdm(range(epochs)):
    for i in tqdm(range(0, len(X), batch_size)):
        batch_x = X[i:i+batch_size]
        batch_y = Y[i:i+batch_size]
        
        #print(batch_x.shape)
        #print(batch_y.shape)
        
        model.zero_grad()
        outputs = model(batch_x)
        loss = loss_function(outputs, batch_y)
        loss.backward()
        
        optimizer.step()
        
    print(f"Epoch: {epoch+1}, loss: {loss*100}%")

torch.save(model.state_dict(),"trained_model.pth")
</code></pre>
<p>The problem i am facing now is that i have trained the model but it just keeps giving me a same prediction every time for example it keeps turning right no matter what the screen input is.</p>

username: sharjeel
cooked: <p>And here is the code where i tested my network.<br>
while(True):</p>
<pre><code>    if not paused:
        model.eval()
        screen = np.array(ImageGrab.grab(bbox=(0,40,800,640)))
        #print("loop took {} seconds".format(time.time()-last_time))
        last_time = time.time()
        screen = cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY)
        screen = cv2.resize(screen, (100,100))
        screen_tensor = torch.Tensor(screen).view(-1,100,100)
        final_screen = screen_tensor.view(-1,1,100,100)
        
        for param in model.parameters():
            param.requires_grad = False
        predictions = model(final_screen)
        print(predictions)
        _, pred = torch.max(predictions, 1)
        print(pred)
        pred = np.int(pred)
        #print(pred)
        
        if pred == 0:
            left()
            
        if pred == 1:
            straight()
        
        if pred == 2:
            breaks()
        
        if pred == 3:
            right()
            
    
    keys = key_check()
    
    if 'T' in keys:
        if paused:
            paused = False
            time.sleep(1)
        else:
            paused = True
            ReleaseKey(A)
            ReleaseKey(S)
            ReleaseKey(D)
            ReleaseKey(W)
            time.sleep(1)
</code></pre>
<p>please help me figure out what is should do for it to work properly</p>