ニューラルネットワークの角度データのエンコード


20

ターゲットデータが角度のベクトル(0〜2 * pi)であるニューラルネットワーク(詳細は重要ではありません)をトレーニングしています。このデータをエンコードする方法に関するアドバイスを探しています。私が現在試みていることは次のとおりです(成功は限られています)。

1)1-of-Cエンコード:設定可能な角度を1000程度の離散的な角度にビン化し、関連するインデックスに1を入力することで特定の角度を示します。これに関する問題は、ネットワークがすべての0を出力することを単に学習することです(これはほぼ正確であるため)。

2)単純なスケーリング:ネットワーク出力範囲([0,1])を[0,2 * pi]にスケーリングしました。ここでの問題は、角度が自然に円形のトポロジを持っていることです(つまり、0.0001と2 * piは実際には互いに隣り合っています)。このタイプのエンコードでは、その情報は失われます。

任意の提案をいただければ幸いです!


1
ソフトマックス出力層を使用する場合、ネットワークがすべてゼロを出力することに問題はないはずです-通常、カタゴリカル(つまり、1-of-C)出力を使用している場合に行うべきです。
リンドンホワイト

7
純粋に投機的なエンコードのアイデアは(私はそれが行われたり、それをテストしたが、私は見ていない見ていませんでした)エンコードあなたの角度(ある:ペアなど)θ θ COS θ 。私はそれがすべてのような値を持つ連続マップだと思う0、および2 π相互に近接しています。これのデモを作成してテストするかもしれないと思います。θθ(θcosθ02π
リンドンホワイト

私はこれについてもう少し考えてきました、そして、それは実際にあなたの損失関数にすべてjsutであるかもしれないと思います。いろいろ試してみたいです。デモを作成しましたが、テストは完了していません。明日いつか実験的な裏付けで詳細な回答を期待してください。(そうでない場合は私を突く)
リンドンホワイト

私は現在、softmaxレイヤーを使用していません。おそらくそれが問題です。機会があれば今日実装します!あなたの(cos、sin)のアイデアは非常に興味深く、特にその範囲を自動的に[-1,1]に入れることが好きです(tanhアクティベーション関数を使用している場合に適しています)。私はあなたのresults1を楽しみにしています
アリハーマン

簡単な更新:softmaxレイヤーを実装しようとしましたが、まだ運がありません。問題は、この問題のために、データの「角度」が何らかの形でエンコードで表現されることが不可欠だということです。カテゴリエンコーディングでは、ターゲットデータのトポロジが失われます。したがって、ネットワークでは0.5 * piと0.05 * piのエラーは同じに見えます(両方とも誤った分類と見なされます)。
アリハーマン

回答:


18

前書き

この質問は本当に興味深いと思います。誰かがそれについて論文を出していると思いますが、それは私の休みなので、参考文献を追いかけたくありません。

したがって、これを出力の表現/エンコードと見なすことができます。これはこの回答で行います。私は、わずかに異なる損失関数を使用できるより良い方法があると考え続けています。(おそらく法とする減算を使用した差の平方和)。π

しかし、実際の答えを先に。

方法

角度は、そのサインとコサインのペアとして表現することを提案します。θ

したがって、エンコード関数は次のとおりです。 およびデコード機能は次のとおりです。θθcosθ
について上記Arctan2は全ての象限方向を維持し、逆正接です)y1y2アークタン2y1y2

理論的には、使用するツールatan2がレイヤー関数としてサポートされている場合、角度を直接操作できます(正確に2つの入力を取り、1つの出力を生成します)。 TensorFlowは現在これを行っており、勾配降下をサポートしていますが、この使用を意図したものはありません。out = atan2(sigmoid(ylogit), sigmoid(xlogit)) 損失関数を使って調べましたmin((pred - out)^2, (pred - out - 2pi)^2)outs = tanh(ylogit), outc = tanh(xlogit)) 損失関数を使用するよりもはるかにトレーニングが悪いことがわかった0.5((sin(pred) - outs)^2 + (cos(pred) - outc)^2。勾配が不連続であるためだと思うatan2

ここでのテストでは、前処理関数として実行します

これを評価するために、タスクを定義しました:

空白の背景の1本の線を表す白黒画像が与えられた場合、その線が「正のx軸」に対してどの角度にあるかを出力します

ランダムな角度の線でこれらの画像をランダムに生成する関数を実装しました(NB:この投稿の以前のバージョンは、ランダムな角度ではなくランダムな傾斜を使用しました。指摘してくれた@Ari Hermanに感謝します。タスクのパフォーマンスを評価するために、いくつかのニューラルネットワークを構築しました。実装の詳細は、このJupyterノートブックに記載されています。コードはすべてJuliaにあり、私はMochaニューラルネットワークライブラリを使用しています。

比較のために、0.1にスケーリングする別の方法と比較して示します。500個のビンに入れて、ソフトラベルsoftmaxを使用します。最後に特に満足しているわけではないので、微調整する必要があると感じています。他の人とは異なり、私は1,000回の反復でのみ試行しましたが、他の2つは1,000回と10,000回実行しました

実験セットアップ

101×101

トレイルごとに1,000のトレーニングと1,000のテスト画像がランダムに生成されました。

評価ネットワークには、幅500の単一の隠れ層がありました。シグモイドニューロンは隠れ層で使用されました。

0.01の固定学習率と0.9の固定運動量で、Stochastic Gradient Decentによってトレーニングされました。

正則化またはドロップアウトは使用されませんでした。畳み込みなどもありませんでした。単純なネットワークで、これらの結果が一般化することを示唆しています。

テストコードでこれらのパラメーターを微調整するのは非常に簡単です。(およびテストでバグを探します)。

結果

私の結果は次のとおりです。

|                        |  500 bins    |  scaled to 0-1 |  Sin/Cos     |  scaled to 0-1 |  Sin/Cos     |
|                        | 1,000 Iter   | 1,000 Iter     | 1,000 iter   | 10,000 Iter    | 10,000 iter  |
|------------------------|--------------|----------------|--------------|----------------|--------------|
| mean_error             | 0.4711263342 | 0.2225284486   | 2.099914718  | 0.1085846429   | 2.1036656318 |
| std(errors)            | 1.1881991421 | 0.4878383767   | 1.485967909  | 0.2807570442   | 1.4891605068 |
| minimum(errors)        | 1.83E-006    | 1.82E-005      | 9.66E-007    | 1.92E-006      | 5.82E-006    |
| median(errors)         | 0.0512168533 | 0.1291033982   | 1.8440767072 | 0.0562908143   | 1.8491085947 |
| maximum(errors)        | 6.0749693965 | 4.9283551248   | 6.2593307366 | 3.735884823    | 6.2704853962 |
| accurancy              | 0.00%        | 0.00%          | 0.00%        | 0.00%          | 0.00%        |
| accurancy_to_point001  | 2.10%        | 0.30%          | 3.70%        | 0.80%          | 12.80%       |
| accurancy_to_point01   | 21.90%       | 4.20%          | 37.10%       | 8.20%          | 74.60%       |
| accurancy_to_point1    | 59.60%       | 35.90%         | 98.90%       | 72.50%         | 99.90%       |

7π4π4

また、さまざまなレベルの粒度で精度を示します。精度は、テストケースの一部であり、相関関係があります。つまりaccuracy_to_point01、出力が真の角度の0.01以内であれば、正しいとカウントされたことを意味します。完璧な結果が得られた表現はありませんが、浮動小数点演算がどのように機能するかを考えると、それはまったく驚くことではありません。

この投稿の履歴を見ると、結果に少しノイズがあり、再実行するたびに少し異なります。ただし、値の一般的な順序とスケールは同じままです。したがって、いくつかの結論を引き出すことができます。

討論

softmaxでのビニングは、実装で何かを台無しにしたかどうかわからないと言ったように、最悪のパフォーマンスを発揮します。ただし、推測率をわずかに上回ります。推測しているだけなら、平均誤差得ることになります。π

sin / cosエンコーディングは、スケーリングされた0-1エンコーディングよりも大幅に優れたパフォーマンスを発揮します。改善は、1,000回のトレーニングの繰り返しで、sin / cosがほとんどのメトリクスで10,000の繰り返しでのスケーリングよりも約3倍優れていることです。

少なくとも10,000回の反復が実行されると、両方ともトレーニングセットでかなり類似した平均二乗誤差が得られるため、これは部分的には一般化の改善に関連すると思います。

101×101

また、絶対的な規模でこのパフォーマンスを超えるには、より優れたニューラルネットワークが必要になる可能性があります。上記の実験セットアップで説明した非常に単純なものではなく。

結論。

ここで調査した表現の中で、sin / cos表現が圧倒的に最高のようです。これは、円の周りを移動するときに滑らかな値を持つという意味で意味があります。また、逆のことがarctan2で行えることも気に入っています。これはエレガントです。

提示されたタスクは、ネットワークに合理的な課題を提示する能力において十分であると思います。本当に、カーブフィッティングをすることを学んでいると思いますがfバツ=y1y2バツ


これは確かに、スタック交換でこれまでに受け取った最も徹底的な応答です。私はジュリアに慣れていないので、コードを調べるのは難しいので...代わりに、Pythonを使用して結果を複製しようとします。調査結果は、今日または明日後に掲載します。
アリハーマン

ビニングのパフォーマンスが悪いことは驚きではありませんでしたが、(cos、sin)メソッドによって(0,1)スケーリングがどの程度優れているかについては驚きました。線の立ち上がりと実行をランダムに選んでサンプルを生成したことに気付きました。これは、角度が均一に分布していないが、勾配が分布している線を生成すると思います。これが(cos、sin)メソッドのパフォーマンスがこれほど優れている理由でしょうか?ターゲットをtan(angle)にした場合はどうなりますか...?
アリハーマン

tan(angle)π/4

本当に再実装する場合は、juliaとnumpyの間、およびMochaとCaffeの間に1対1のマップが近いはずです。読みにくいコードの特定の部分はありますか?ジュリアは理解しやすい言語でなければなりません。だから、私は何か奇妙なことをしたかもしれません。
リンドンホワイト

私はあなたのコードを読んでしまいましたが、すべてが正しいようです。それでも、私は自分のバージョンを書きたかったのです。なぜなら、そうすることは通常は有益だからです。私の実装はあなたのものとは少し異なりますので、結果を比較することは興味深いでしょう。数時間以内に投稿します。
アリハーマン

5

Lyndon Whiteの提案されたエンコーディングとビン化されたアプローチを比較する別のPython実装があります。以下のコードは、次の出力を生成しました。

Training Size: 100
Training Epochs: 100
Encoding: cos_sin
Test Error: 0.017772154610047136
Encoding: binned
Test Error: 0.043398792553251526

Training Size: 100
Training Epochs: 500
Encoding: cos_sin
Test Error: 0.015376604917819397
Encoding: binned
Test Error: 0.032942592915322394

Training Size: 1000
Training Epochs: 100
Encoding: cos_sin
Test Error: 0.007544091937411164
Encoding: binned
Test Error: 0.012796594492198667

Training Size: 1000
Training Epochs: 500
Encoding: cos_sin
Test Error: 0.0038051515079569097
Encoding: binned
Test Error: 0.006180633805557207

θcosθθcosθ

import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torch.utils.data

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")


class Net(nn.Module):
    def __init__(self, input_size, hidden_size, num_out):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.sigmoid = nn.Sigmoid()
        self.fc2 = nn.Linear(hidden_size, num_out)

    def forward(self, x):
        out = self.fc1(x)
        out = self.sigmoid(out)
        out = self.fc2(out)
        return out


def gen_train_image(angle, side, thickness):
    image = np.zeros((side, side))
    (x_0, y_0) = (side / 2, side / 2)
    (c, s) = (np.cos(angle), np.sin(angle))
    for y in range(side):
        for x in range(side):
            if (abs((x - x_0) * c + (y - y_0) * s) < thickness / 2) and (
                    -(x - x_0) * s + (y - y_0) * c > 0):
                image[x, y] = 1

    return image.flatten()


def gen_data(num_samples, side, num_bins, thickness):
    angles = 2 * np.pi * np.random.uniform(size=num_samples)
    X = [gen_train_image(angle, side, thickness) for angle in angles]
    X = np.stack(X)

    y = {"cos_sin": [], "binned": []}
    bin_size = 2 * np.pi / num_bins
    for angle in angles:
        idx = int(angle / bin_size)
        y["binned"].append(idx)
        y["cos_sin"].append(np.array([np.cos(angle), np.sin(angle)]))

    for enc in y:
        y[enc] = np.stack(y[enc])

    return (X, y, angles)


def get_model_stuff(train_y, input_size, hidden_size, output_sizes,
                    learning_rate, momentum):
    nets = {}
    optimizers = {}

    for enc in train_y:
        net = Net(input_size, hidden_size, output_sizes[enc])
        nets[enc] = net.to(device)
        optimizers[enc] = torch.optim.SGD(net.parameters(), lr=learning_rate,
                                          momentum=momentum)

    criterions = {"binned": nn.CrossEntropyLoss(), "cos_sin": nn.MSELoss()}
    return (nets, optimizers, criterions)


def get_train_loaders(train_X, train_y, batch_size):
    train_X_tensor = torch.Tensor(train_X)

    train_loaders = {}

    for enc in train_y:
        if enc == "binned":
            train_y_tensor = torch.tensor(train_y[enc], dtype=torch.long)
        else:
            train_y_tensor = torch.tensor(train_y[enc], dtype=torch.float)

        dataset = torch.utils.data.TensorDataset(train_X_tensor, train_y_tensor)
        train_loader = torch.utils.data.DataLoader(dataset=dataset,
                                                   batch_size=batch_size,
                                                   shuffle=True)
        train_loaders[enc] = train_loader

    return train_loaders


def show_image(image, side):
    img = plt.imshow(np.reshape(image, (side, side)), interpolation="nearest",
                     cmap="Greys")
    plt.show()


def main():
    side = 101
    input_size = side ** 2
    thickness = 5.0
    hidden_size = 500
    learning_rate = 0.01
    momentum = 0.9
    num_bins = 500
    bin_size = 2 * np.pi / num_bins
    half_bin_size = bin_size / 2
    batch_size = 50
    output_sizes = {"binned": num_bins, "cos_sin": 2}
    num_test = 1000

    (test_X, test_y, test_angles) = gen_data(num_test, side, num_bins,
                                             thickness)

    for num_train in [100, 1000]:

        (train_X, train_y, train_angles) = gen_data(num_train, side, num_bins,
                                                    thickness)
        train_loaders = get_train_loaders(train_X, train_y, batch_size)

        for epochs in [100, 500]:

            (nets, optimizers, criterions) = get_model_stuff(train_y, input_size,
                                                             hidden_size, output_sizes,
                                                             learning_rate, momentum)

            for enc in train_y:
                optimizer = optimizers[enc]
                net = nets[enc]
                criterion = criterions[enc]

                for epoch in range(epochs):
                    for (i, (images, ys)) in enumerate(train_loaders[enc]):
                        optimizer.zero_grad()

                        outputs = net(images.to(device))
                        loss = criterion(outputs, ys.to(device))
                        loss.backward()
                        optimizer.step()


            print("Training Size: {0}".format(num_train))
            print("Training Epochs: {0}".format(epochs))
            for enc in train_y:
                net = nets[enc]
                preds = net(torch.tensor(test_X, dtype=torch.float).to(device))
                if enc == "binned":
                    pred_bins = np.array(preds.argmax(dim=1).detach().cpu().numpy(),
                                         dtype=np.float)
                    pred_angles = bin_size * pred_bins + half_bin_size
                else:
                    pred_angles = torch.atan2(preds[:, 1], preds[:, 0]).detach().cpu().numpy()
                    pred_angles[pred_angles < 0] = pred_angles[pred_angles < 0] + 2 * np.pi

                print("Encoding: {0}".format(enc))
                print("Test Error: {0}".format(np.abs(pred_angles - test_angles).mean()))

            print()


if __name__ == "__main__":
    main()

3

これがあなたの実験の私のPythonバージョンです。実装の詳細の多くを同じに保ちました。特に、同じイメージサイズ、ネットワークレイヤーサイズ、学習率、勢い、成功指標を使用しています。

テストされた各ネットワークには、ロジスティックニューロンを含む1つの隠れ層(サイズ= 500)があります。前述のように、出力ニューロンは線形またはソフトマックスです。ランダムに生成された独立した1,000枚のトレーニング画像と1,000枚のテスト画像を使用しました(繰り返しが発生する可能性があります)。トレーニングは、トレーニングセットの50回の反復で構成されました。

ビニングと「ガウス」エンコーディング(作成した名前。ターゲット出力ベクトルの形式がexp(-pi *([1,2,3、... 、500]-idx)** 2)idxは正しい角度に対応するインデックスです)。コードは次のとおりです。ここに私の結果があります:

(cos、sin)エンコーディングのテストエラー:

1,000個のトレーニング画像、1,000個のテスト画像、50回の反復、線形出力

  • 平均:0.0911558142071

  • 中央値:0.0429723541743

  • 最小:2.77769843793e-06

  • 最大:6.2608513539

  • 0.1の精度:85.2%

  • 0.01の精度:11.6%

  • 0.001の精度:1.0%

[-1,1]エンコーディングのテストエラー:

1,000個のトレーニング画像、1,000個のテスト画像、50回の反復、線形出力

  • 平均:0.234181700523

  • 中央値:0.17460197307

  • 最小:0.000473665840258

  • 最大:6.00637777237

  • 0.1の精度:29.9%

  • 0.01の精度:3.3%

  • 0.001の精度:0.1%

500分の1エンコーディングのテストエラー:

1,000個のトレーニング画像、1,000個のテスト画像、50回の反復、softmax出力

  • 平均:0.0298767021922

  • 中央値:0.00388858079174

  • 最小:4.08712407829e-06

  • 最大:6.2784479965

  • 0.1の精度:99.6%

  • 0.01の精度:88.9%

  • 0.001の精度:13.5%

ガウスエンコーディングのテストエラー:

1,000個のトレーニング画像、1,000個のテスト画像、50回の反復、softmax出力

  • 平均:0.0296905377463
  • 中央値:0.00365867335107
  • 最小:4.08712407829e-06
  • 最大:6.2784479965
  • 0.1の精度:99.6%
  • 0.01の精度:90.8%
  • 0.001の精度:14.3%

私たちの結果が互いに矛盾しているように見える理由を理解することはできませんが、さらに調査する価値があります。

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 13 16:59:53 2016

@author: Ari
"""

from numpy import savetxt, loadtxt, round, zeros, sin, cos, arctan2, clip, pi, tanh, exp, arange, dot, outer, array, shape, zeros_like, reshape, mean, median, max, min
from numpy.random import rand, shuffle
import matplotlib.pyplot as plt

###########
# Functions
###########

# Returns a B&W image of a line represented as a binary vector of length width*height
def gen_train_image(angle, width, height, thickness):
    image = zeros((height,width))
    x_0,y_0 = width/2, height/2
    c,s = cos(angle),sin(angle)
    for y in range(height):
        for x in range(width):
            if abs((x-x_0)*c + (y-y_0)*s) < thickness/2 and -(x-x_0)*s + (y-y_0)*c > 0:
                image[x,y] = 1
    return image.flatten()

# Display training image    
def display_image(image,height, width):    
    img = plt.imshow(reshape(image,(height,width)), interpolation = 'nearest', cmap = "Greys")
    plt.show()    

# Activation function
def sigmoid(X):
    return 1.0/(1+exp(-clip(X,-50,100)))

# Returns encoded angle using specified method ("binned","scaled","cossin","gaussian")
def encode_angle(angle, method):
    if method == "binned": # 1-of-500 encoding
        X = zeros(500)
        X[int(round(250*(angle/pi + 1)))%500] = 1
    elif method == "gaussian": # Leaky binned encoding
        X = array([i for i in range(500)])
        idx = 250*(angle/pi + 1)
        X = exp(-pi*(X-idx)**2)
    elif method == "scaled": # Scaled to [-1,1] encoding
        X = array([angle/pi])
    elif method == "cossin": # Oxinabox's (cos,sin) encoding
        X = array([cos(angle),sin(angle)])
    else:
        pass
    return X

# Returns decoded angle using specified method
def decode_angle(X, method):
    if method == "binned" or method == "gaussian": # 1-of-500 or gaussian encoding
        M = max(X)
        for i in range(len(X)):
            if abs(X[i]-M) < 1e-5:
                angle = pi*i/250 - pi
                break
#        angle = pi*dot(array([i for i in range(500)]),X)/500  # Averaging
    elif method == "scaled": # Scaled to [-1,1] encoding
        angle = pi*X[0]
    elif method == "cossin": # Oxinabox's (cos,sin) encoding
        angle = arctan2(X[1],X[0])
    else:
        pass
    return angle

# Train and test neural network with specified angle encoding method
def test_encoding_method(train_images,train_angles,test_images, test_angles, method, num_iters, alpha = 0.01, alpha_bias = 0.0001, momentum = 0.9, hid_layer_size = 500):
    num_train,in_layer_size = shape(train_images)
    num_test = len(test_angles)

    if method == "binned":
        out_layer_size = 500
    elif method == "gaussian":
        out_layer_size = 500
    elif method == "scaled":
        out_layer_size = 1
    elif method == "cossin":
        out_layer_size = 2
    else:
        pass

    # Initial weights and biases
    IN_HID = rand(in_layer_size,hid_layer_size) - 0.5 # IN --> HID weights
    HID_OUT = rand(hid_layer_size,out_layer_size) - 0.5 # HID --> OUT weights
    BIAS1 = rand(hid_layer_size) - 0.5 # Bias for hidden layer
    BIAS2 = rand(out_layer_size) - 0.5 # Bias for output layer

    # Initial weight and bias updates
    IN_HID_del = zeros_like(IN_HID)
    HID_OUT_del = zeros_like(HID_OUT)
    BIAS1_del = zeros_like(BIAS1)
    BIAS2_del = zeros_like(BIAS2)

    # Train
    for j in range(num_iters):
        for i in range(num_train):
            # Get training example
            IN = train_images[i]
            TARGET = encode_angle(train_angles[i],method) 

            # Feed forward and compute error derivatives
            HID = sigmoid(dot(IN,IN_HID)+BIAS1)

            if method == "binned" or method == "gaussian": # Use softmax
                OUT = exp(clip(dot(HID,HID_OUT)+BIAS2,-100,100))
                OUT = OUT/sum(OUT)
                dACT2 = OUT - TARGET
            elif method == "cossin" or method == "scaled": # Linear
                OUT = dot(HID,HID_OUT)+BIAS2 
                dACT2 = OUT-TARGET 
            else:
                print("Invalid encoding method")

            dHID_OUT = outer(HID,dACT2)
            dACT1 = dot(dACT2,HID_OUT.T)*HID*(1-HID)
            dIN_HID = outer(IN,dACT1)
            dBIAS1 = dACT1
            dBIAS2 = dACT2

            # Update the weight updates 
            IN_HID_del = momentum*IN_HID_del + (1-momentum)*dIN_HID
            HID_OUT_del = momentum*HID_OUT_del + (1-momentum)*dHID_OUT
            BIAS1_del = momentum*BIAS1_del + (1-momentum)*dBIAS1
            BIAS2_del = momentum*BIAS2_del + (1-momentum)*dBIAS2

            # Update the weights
            HID_OUT -= alpha*dHID_OUT
            IN_HID -= alpha*dIN_HID
            BIAS1 -= alpha_bias*dBIAS1
            BIAS2 -= alpha_bias*dBIAS2

    # Test
    test_errors = zeros(num_test)
    angles = zeros(num_test)
    target_angles = zeros(num_test)
    accuracy_to_point001 = 0
    accuracy_to_point01 = 0
    accuracy_to_point1 = 0

    for i in range(num_test):

        # Get training example
        IN = test_images[i]
        target_angle = test_angles[i]

        # Feed forward
        HID = sigmoid(dot(IN,IN_HID)+BIAS1)

        if method == "binned" or method == "gaussian":
            OUT = exp(clip(dot(HID,HID_OUT)+BIAS2,-100,100))
            OUT = OUT/sum(OUT)
        elif method == "cossin" or method == "scaled":
            OUT = dot(HID,HID_OUT)+BIAS2 

        # Decode output 
        angle = decode_angle(OUT,method)

        # Compute errors
        error = abs(angle-target_angle)
        test_errors[i] = error
        angles[i] = angle

        target_angles[i] = target_angle
        if error < 0.1:
            accuracy_to_point1 += 1
        if error < 0.01: 
            accuracy_to_point01 += 1
        if error < 0.001:
            accuracy_to_point001 += 1

    # Compute and return results
    accuracy_to_point1 = 100.0*accuracy_to_point1/num_test
    accuracy_to_point01 = 100.0*accuracy_to_point01/num_test
    accuracy_to_point001 = 100.0*accuracy_to_point001/num_test

    return mean(test_errors),median(test_errors),min(test_errors),max(test_errors),accuracy_to_point1,accuracy_to_point01,accuracy_to_point001

# Dispaly results
def display_results(results,method):
    MEAN,MEDIAN,MIN,MAX,ACC1,ACC01,ACC001 = results
    if method == "binned":
        print("Test error for 1-of-500 encoding:")
    elif method == "gaussian":
        print("Test error for gaussian encoding: ")
    elif method == "scaled":
        print("Test error for [-1,1] encoding:")
    elif method == "cossin":
        print("Test error for (cos,sin) encoding:")
    else:
        pass
    print("-----------")
    print("Mean: "+str(MEAN))
    print("Median: "+str(MEDIAN))
    print("Minimum: "+str(MIN))
    print("Maximum: "+str(MAX))
    print("Accuracy to 0.1: "+str(ACC1)+"%")
    print("Accuracy to 0.01: "+str(ACC01)+"%")
    print("Accuracy to 0.001: "+str(ACC001)+"%")
    print("\n\n")


##################
# Image parameters
##################
width = 100 # Image width
height = 100 # Image heigth
thickness = 5.0 # Line thickness

#################################
# Generate training and test data
#################################
num_train = 1000
num_test = 1000
test_images = []
test_angles = []
train_images = []
train_angles = []
for i in range(num_train):
    angle = pi*(2*rand() - 1)
    train_angles.append(angle)
    image = gen_train_image(angle,width,height,thickness)
    train_images.append(image)
for i in range(num_test):
    angle = pi*(2*rand() - 1)
    test_angles.append(angle)
    image = gen_train_image(angle,width,height,thickness)
    test_images.append(image)
train_angles,train_images,test_angles,test_images = array(train_angles),array(train_images),array(test_angles),array(test_images)



###########################
# Evaluate encoding schemes
###########################
num_iters = 50

# Train with cos,sin encoding
method = "cossin"
results1 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results1,method)

# Train with scaled encoding
method = "scaled"
results3 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results3,method)

# Train with binned encoding
method = "binned"
results2 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results2,method)

# Train with gaussian encoding
method = "gaussian"
results4 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results4,method)

クール、キーが異なります。各画像を1回だけトレーニングします。各画像を1,000回、または10,000回トレーニングしています。特に比較的少量のデータでトレーニングを行う場合、トレーニングデータは複数回反復されます(これを学習するのに、公開できない学部論文が1つだけ必要でしたが、それは別の話です)。そうは言っても、テーブルに1イター列を追加する必要があります。それは有益だろう
リンドンホワイト

ターゲットが似ている(ただし同一ではない)画像をトレーニングすると、そのネットワークにも同様に影響すると思います。それが当てはまる場合は、小さなトレーニングセットで何度も繰り返すのではなく、トレーニング対象のランダムイメージの数を単純に増やすことで問題なく動作するはずです。これはそうではないと言っていますか?
アリハーマン

これは似ていますが、このタスク例では、最終的にすべての可能な画像を表示するため、テストが電車と重複するため、テストの一般化は機能しません。さらに重要なのは、100,000枚のトレーニングイメージを実行することです。これは、<1000 * 1000トレーニングイメージ*反復です。
リンドンホワイト

あなたは正しいです、私はその問題を修正します。コードにはさらに重大な問題があります。(cos、sin)表現に必要な負の値を生成できないロジスティックニューロンを使用しています。ど!コードを修正し、できるだけ早く再投稿します。
アリハーマン

(まだ行っていない場合)Graident Checkを実行することに興味があるかもしれません。これは、ニューラルネットワークをゼロから実装する場合に役立ちます。Re:ニューロン:ええ、シグモイドの隠れ層の上に線形出力層があります
リンドンホワイト

1

角度をエンコードする別の方法は、2つの値のセットとしてです。

y1 = max(0、theta)

y2 = max(0、-theta)

theta_out = y1-y2

これは、勾配がtheta = 0で未定義であるという点でarctan2と同様の問題があります。ネットワークをトレーニングして他のエンコーディングと比較する時間はありませんが、この論文ではこの手法はかなり成功したように見えます。


1
これは、ある投稿で別の質問と答えが混在しているようです。このサイトの動作は、フォーラムとは少し異なります。ここでの回答は、元の質問への回答に集中する必要があります。また、別の質問やコメントがある場合は、そのように投稿する必要があります。
カロリス・コンセビチウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.