前回、単純なTransformerで学習を試した。
出力層を全てのトークンの全結合としていたため、パラメータ数の半分近くを占めており効率が悪かった。
今回は、出力層の全結合の前に、カーネルサイズ1の畳み込み層を追加することで、チャンネル方向に圧縮を行い、学習が効率化できるか試した。
トークンの方向に圧縮する場合と、埋め込みの次元方向に圧縮する場合の2パターンを試した。
トークン方向に圧縮
方策と価値の出力層の全結合の前に、カーネルサイズ1のConv1dを追加し、トークンを16に圧縮する。
def __init__(self, ntoken=96, d_model=256, nhead=8, dim_feedforward=256, num_layers=8, dropout=0.1): ... self.policy_conv = nn.Conv1d(ntoken, 16, 1, bias=False) self.policy_norm = nn.BatchNorm1d(d_model * 16) self.policy_fc = nn.Linear(d_model * 16, 1496) self.value_conv = nn.Conv1d(ntoken, 16, 1, bias=False) self.value_norm1 = nn.BatchNorm1d(d_model * 16) self.value_fc1 = nn.Linear(d_model * 16, 256, bias=False) def forward(self, src): ... policy = self.policy_conv(x) policy = F.relu(self.policy_norm(policy.flatten(1))) policy = self.policy_fc(policy) value = self.value_conv(x) value = F.relu(self.value_norm1(value.flatten(1))) value = F.relu(self.value_norm2(self.value_fc1(value))) value = self.value_fc2(value) return policy, value
埋め込みの次元方向に圧縮
方策と価値の出力層の全結合の前に、カーネルサイズ1のConv1dを追加し、埋め込みの次元を1/8に圧縮する。
forwardで、Conv1dの前にtransposeを行い、埋め込みの次元をチャンネルの次元にする。
def __init__(self, ntoken=96, d_model=256, nhead=8, dim_feedforward=256, num_layers=8, dropout=0.1): ... self.policy_conv = nn.Conv1d(d_model, d_model // 8, 1, bias=False) self.policy_norm = nn.BatchNorm1d(ntoken * d_model // 8) self.policy_fc = nn.Linear(ntoken * d_model // 8, 1496) self.value_conv = nn.Conv1d(d_model, d_model // 8, 1, bias=False) self.value_norm1 = nn.BatchNorm1d(ntoken * d_model // 8) self.value_fc1 = nn.Linear(ntoken * d_model // 8, 256, bias=False) def forward(self, src): ... x = x.transpose(1, 2) policy = self.policy_conv(x) policy = F.relu(self.policy_norm(policy.flatten(1))) policy = self.policy_fc(policy) value = self.value_conv(x) value = F.relu(self.value_norm1(value.flatten(1))) value = F.relu(self.value_norm2(self.value_fc1(value))) value = self.value_fc2(value) return policy, value
結果
トークン方向に圧縮するパターン(ntoken)と、埋め込みの次元方向に圧縮するパターン(d_model)で、それぞれ条件を変えて比較した。
d model : 埋め込む次元
dim FF : TransformerのFF層の次元
n head : MultiHeadAttensionのヘッド数
num layers : Transformerのレイヤー数
データは前回と同じで、1エポックだけ学習した。
パターン | out channels | d model | dim FF | n head | num layers | val loss | policy acc. | value acc. |
---|---|---|---|---|---|---|---|---|
resnet20 | 2.677 | 0.391 | 0.665 | |||||
baseline | 96 | 256 | 256 | 8 | 8 | 3.088 | 0.336 | 0.652 |
ntoken | 16 | 256 | 256 | 8 | 8 | 3.599 | 0.305 | 0.655 |
ntoken | 16 | 512 | 256 | 8 | 8 | 3.414 | 0.323 | 0.657 |
ntoken | 16 | 768 | 256 | 8 | 8 | 3.338 | 0.326 | 0.660 |
d_model | d_model//8 | 256 | 256 | 8 | 8 | 3.213 | 0.333 | 0.640 |
d_model | d_model//8 | 512 | 256 | 8 | 8 | 3.072 | 0.345 | 0.657 |
d_model | d_model//8 | 512 | 512 | 8 | 8 | 3.067 | 0.346 | 0.655 |
d_model | d_model//8 | 512 | 512 | 4 | 8 | 3.071 | 0.345 | 0.657 |
d_model | d_model//8 | 768 | 512 | 8 | 8 | 3.063 | 0.345 | 0.644 |
d_model | d_model//8 | 768 | 512 | 12 | 8 | 3.051 | 0.347 | 0.644 |
d_model | d_model//8 | 768 | 512 | 12 | 10 | 3.024 | 0.348 | 0.659 |
Conv1Dで次元を圧縮することで、ベースラインに比べて、精度が下がっている。
埋め込みの次元方向に圧縮する方が、若干精度が良い。
他の条件を変えてみたが、いずれもResnet20ブロックのモデルに比べると精度が低い。