[PYTHON] I tried to learn the angle from sin and cos with chainer

Introduction

Until previous, we learned only 1 input and 1 output from sin like angle (theta), but this time we learned angle from sin and cos I would like to learn 2 inputs and 1 output.

environment

content of study

Learn the angle (theta) from sin and cos (0-2π).

[training data]

Training data


def get_dataset(N):
    theta = np.linspace(0, 2 * np.pi, N)
    sin = np.sin(theta)
    cos = np.cos(theta)

    x = np.c_[sin, cos]
    y = theta

    return x, y

Implementation

Setting the number of units

Since the number of units in the input layer (in_units) and output layer (out_units) is set, the versatility is slightly increased compared to the previous code.

Batch learning


class MyChain(Chain):
    def __init__(self, in_units=1, n_units=10, out_units=1):
        super(MyChain, self).__init__(
             l1=L.Linear(in_units, n_units),
             l2=L.Linear(n_units, n_units),
             l3=L.Linear(n_units, out_units))
        self.in_units = in_units
        self.out_units = out_units

Learning parameters

All parameters are appropriate.

Whole code

The entire


# -*- coding: utf-8 -*-

#Import from one end for the time being
import numpy as np
import chainer
from chainer import cuda, Function, gradient_check, Variable, optimizers, serializers, utils
from chainer import Link, Chain, ChainList
import chainer.functions as F
import chainer.links as L
import time
from matplotlib import pyplot as plt

#data
def get_dataset(N):
    theta = np.linspace(0, 2 * np.pi, N)
    sin = np.sin(theta)
    cos = np.cos(theta)

    x = np.c_[sin, cos]
    y = theta

    return x, y

#neural network
class MyChain(Chain):
    def __init__(self, in_units=1, n_units=10, out_units=1):
        super(MyChain, self).__init__(
             l1=L.Linear(in_units, n_units),
             l2=L.Linear(n_units, n_units),
             l3=L.Linear(n_units, out_units))
        self.in_units = in_units
        self.out_units = out_units

    def __call__(self, x_data, y_data):
        x = Variable(x_data.astype(np.float32).reshape(len(x_data),self.in_units)) #Convert to Variable object
        y = Variable(y_data.astype(np.float32).reshape(len(y_data),self.out_units)) #Convert to Variable object
        return F.mean_squared_error(self.predict(x), y)

    def  predict(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        h3 = self.l3(h2)
        return h3

    def get_predata(self, x):
        return self.predict(Variable(x.astype(np.float32).reshape(len(x),self.in_units))).data

# main
if __name__ == "__main__":

    #Training data
    N = 1000
    x_train, y_train = get_dataset(N)

    #test data
    N_test = 900
    x_test, y_test = get_dataset(N_test)

    #Learning parameters
    batchsize = 10
    n_epoch = 500
    in_units = 2
    n_units = 100
    out_units = 1

    #Modeling
    model = MyChain(in_units, n_units, out_units)
    optimizer = optimizers.Adam()
    optimizer.setup(model)

    #Learning loop
    print "start..."
    train_losses =[]
    test_losses =[]
    start_time = time.time()
    for epoch in range(1, n_epoch + 1):

        # training
        perm = np.random.permutation(N)
        sum_loss = 0
        for i in range(0, N, batchsize):
            x_batch = x_train[perm[i:i + batchsize]]
            y_batch = y_train[perm[i:i + batchsize]]
            model.zerograds()
            loss = model(x_batch,y_batch)
            sum_loss += loss.data * batchsize
            loss.backward()
            optimizer.update()

        average_loss = sum_loss / N
        train_losses.append(average_loss)

        # test
        loss = model(x_test, y_test)
        test_losses.append(loss.data)

        #Output learning process
        if epoch % 10 == 0:
            print "epoch: {}/{} train loss: {} test loss: {}".format(epoch, n_epoch, average_loss, loss.data)

    interval = int(time.time() - start_time)
    print "Execution time(normal): {}sec".format(interval)
    print "end"

    #Graphing the error
    plt.plot(train_losses, label = "train_loss")
    plt.plot(test_losses, label = "test_loss")
    plt.yscale('log')
    plt.legend()
    plt.grid(True)
    plt.title("loss")
    plt.xlabel("epoch")
    plt.ylabel("loss")
    plt.show()

    #Graphing learning results
    sin, cos = np.hsplit(x_test ,in_units)
    theta = y_test
    test = model.get_predata(x_test)

    plt.subplot(3, 1, 1)
    plt.plot(theta, sin, "b", label = "sin")
    plt.legend(loc = "upper left")
    plt.grid(True)
    plt.xlim(0, 2 * np.pi)
    plt.ylim(-1.2, 1.2)

    plt.subplot(3, 1, 2)
    plt.plot(theta, cos, "g", label = "cos")
    plt.legend(loc = "upper left")
    plt.grid(True)
    plt.xlim(0, 2 * np.pi)
    plt.ylim(-1.2, 1.2)

    plt.subplot(3, 1, 3)
    plt.plot(theta, theta, "r", label = "theta")
    plt.plot(theta, test, "c", label = "test")
    plt.legend(loc = "upper left")
    plt.grid(True)
    plt.xlim(0, 2 * np.pi)
    plt.ylim(-0.5, 7)

    plt.tight_layout()
    plt.show()

Execution result

error

If the number of epochs is 500, the error is large. Moreover, since the degree of error reduction is becoming saturated, it is unlikely that further reduction can be expected unless the number of epochs is significantly increased.

resolver_simple_loss.png

Learning results

Since the output is linear, the error does not seem to be so large.

resolver_simple_test.png

When the input is multiplied by the carrier

I also confirmed the case where the input sin and cos were multiplied by the carrier wave. (3 inputs and 1 output including carrier wave) This is the same principle as the resolver that detects the angle of the motor.

Learning data with carrier wave


def get_dataset(N):
    theta = np.linspace(0, 2 * np.pi, N)
    ref = np.sin(40 * theta) #Carrier
    sin = np.sin(theta) * ref
    cos = np.cos(theta) * ref

    x = np.c_[sin, cos, ref]
    y = theta

    return x, y

# in_Change units to 3

It can be confirmed that the error is large even in appearance because the input is complicated. Harmonic components remain.

resolver_real_test.png

Summary

Although the error is large, we were able to learn the angle from sin and cos. (2 inputs and 1 output) The angle could also be learned from the waveform of the resolver multiplied by the carrier wave. However, a harmonic component was generated. It was a trivial learning content, so I thought I could learn more accurately, but I was surprised that the error was large. In the future, I want to learn more complicated contents, so I can think of the future ...

Recommended Posts

I tried to learn the angle from sin and cos with chainer
I tried to learn the sin function with chainer
I tried to implement and learn DCGAN with PyTorch
I tried to approximate the sin function using chainer
I tried to approximate the sin function using chainer (re-challenge)
I tried to learn logical operations with TF Learn
I tried to express sadness and joy with the stable marriage problem.
I tried to save the data with discord
765 I tried to identify the three professional families by CNN (with Chainer 2.0.0)
I tried to control the network bandwidth and delay with the tc command
[Introduction to AWS] I tried porting the conversation app and playing with text2speech @ AWS ♪
I tried to pass the G test and E qualification by training from 50
I tried to read and save automatically with VOICEROID2 2
I tried to detect the iris from the camera image
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
I tried to automatically read and save with VOICEROID2
I tried to solve the problem with Python Vol.1
I tried to implement Grad-CAM with keras and tensorflow
I read the Chainer reference (updated from time to time)
I tried to learn PredNet
I tried to automate the article update of Livedoor blog with Python and selenium.
I tried to compare the processing speed with dplyr of R and pandas of Python
I tried to predict and submit Titanic survivors with Kaggle
I tried to find the entropy of the image with python
I tried to simulate how the infection spreads with Python
I tried to analyze the whole novel "Weathering with You" ☔️
I tried using the Python library from Ruby with PyCall
I tried to find the average of the sequence with TensorFlow
I tried to illustrate the time and time in C language
I tried to display the time and today's weather w
I tried to implement ListNet of rank learning with Chainer
I tried to enumerate the differences between java and python
I tried to make GUI tic-tac-toe with Python and Tkinter
I tried changing the python script from 2.7.11 to 3.6.0 on windows10
I tried to divide the file into folders with Python
I tried to get various information from the codeforces API
I tried to automatically post to ChatWork at the time of deployment with fabric and ChatWork Api
I made a server with Python socket and ssl and tried to access it from a browser
Sentiment analysis with natural language processing! I tried to predict the evaluation from the review text
I also tried to imitate the function monad and State monad with a generator in Python
I tried to summarize the languages that beginners should learn from now on by purpose
I tried to move the ball
I tried to estimate the interval.
Introduction to AI creation with Python! Part 1 I tried to classify and predict what the numbers are from the handwritten number images.
I tried to describe the traffic in real time with WebSocket
Repeat with While. Scripts to Tweet and search from the terminal
I tried to automate the watering of the planter with Raspberry Pi
I tried to process the image in "sketch style" with OpenCV
I tried to make a periodical process with Selenium and Python
I tried to get started with Bitcoin Systre on the weekend
I tried sending an email from the Sakura server with flask-mail
I tried to predict by letting RNN learn the sine wave
I tried to create Bulls and Cows with a shell program
I tried to process the image in "pencil style" with OpenCV
I tried to expand the size of the logical volume with LVM
Learn Bayesian statistics from the basics to learn the M-H and HMC methods
I tried to cut out a still image from the video
I tried to easily detect facial landmarks with python and dlib
I tried running the DNN part of OpenPose with Chainer CPU
I tried to extract players and skill names from sports articles