It seems that when you do .backward its also backprop’ing through to the training data, i.e., batch_y. If you detach batch_y, it should be ok.
        for k, (batch_x, batch_y) in enumerate(train_loader):

            model.zero_grad()
            optimizer.zero_grad()

            outputs = model(batch_x)


            # loss = F.mse_loss(outputs, batch_y)
            loss = F.mse_loss(outputs,batch_y.detach())

            loss.backward()
            optimizer.step()

This is because your lin, and conv that you created do require gradients, and thus the datasets you create from that also require gradients.