FC2カウンター FPGAの部屋 2022年12月
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

AXI4-Stream 32 ビット入出力のガボール・フィルタを変更する3

AXI4-Stream 32 ビット入出力のガボール・フィルタを変更する2”の続き。

Vitis HLS 2022.2 を使用して、AXI4-Stream 32 ビット入出力のガボール・フィルタ Gabor_Filter_lh_2 を Gabor_Filter_lh_3 として作成することにしたということで、前回は、C シミュレーションを行って、C コードの合成を行ったところ、Estimated が 10.213 ns と 10 ns をオーバーしてしまったので、 Gabor_Filter_lh_3.cpp を書き換えた。今回は、C コードの合成をやり直したところ、Estimated は 7.385 ns に改善した。C/RTL 協調シミュレーション、Export RTL、Implementation を行った。

Gabor_Filter_lh_3.cpp を変更したので、C コードの合成をやり直した。
C コードの合成結果で、前回示したクリティカル・パスの部分を示す。
icmp が一番レイテンシが大きいようで、2.5 ns 程度になるようだ。これを排除できればレイテンシが短くなる。icmp は引き算が入るので、レイテンシが大きいのだろう?
Zybot2_66_221231.png

C コードの合成結果を貼っておく。
Zybot2_67_221231.png

C/RTL 協調シミュレーションを行った。結果を示す。
Zybot2_68_221231.png

64 x 48 ピクセル = 3072 ピクセルを 2 画面分で 6114 ピクセル分ガボール・フィルタ処理を行っているので、1 クロック / ピクセルに近くなっている。

C/RTL 協調シミュレーション波形を示す。
Zybot2_69_221231.png

Export RTL を行った。

Implementation を行った。結果を示す。
Zybot2_70_221231.png

CP achieved post-implementation は 9.329 ns で問題無さそうだ。
  1. 2022年12月31日 05:10 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

AXI4-Stream 32 ビット入出力のガボール・フィルタを変更する2

AXI4-Stream 32 ビット入出力のガボール・フィルタを変更する1”の続き。

Vitis HLS 2022.2 を使用して、AXI4-Stream 32 ビット入出力のガボール・フィルタ Gabor_Filter_lh_2 を Gabor_Filter_lh_3 として作成することにしたということで、前回は、ソースコードを貼って、Vitis HLS 2022.2 の Gabor_Filter_lh_3 プロジェクトを作成した。今回は、C シミュレーションを行って、C コードの合成を行ったところ、Estimated が 10.213 ns と 10 ns をオーバーしてしまったので、 Gabor_Filter_lh_3.cpp を書き換えた。

C シミュレーションを行った。結果を示す。
Zybot2_63_221229.png

Gabor_Filter_lh_3/solution1/csim/build ディレクトリを示す。
???0.bmp が左白線用パラメータのガボール・フィルタ画像で、???0.bmp が右白線パラメータのガボール・フィルタ画像を示す。
Zybot2_64_221229.png

C コードの合成を行ったが、Estimated が 10.213 ns と 10 ns をオーバーしてしまった。
Zybot2_65_221229.png

Estimated は、Uncertainty を大きくしても変わらなかった。
そこで、クリティカル・パスを調査した。
その結果、最後の”('icmp_ln54', Gabor_Filter_lh_3/Gabor_Filter_lh_3.cpp:54) [315] (2.47 ns)”は回避することができそうだ。
Zybot2_66_221230.png

この if 文は画像の最初の user = 1 の時のピクセルはすでに do while() 文で読み込まれているので、最初だけピクセルを読まないようにする文だ。
この文は、最初から user = 1 だったら無くすことができる。その場合は、do while() 文も削除する。
もし最初に user = 1 じゃない場合は、最初に user = 1 になってから受け取るような IP を置いておけば良いはずだ。
その様に改良した Gabor_Filter_lh_3.cpp を示す。

// Gabor_Fiter_lh_3.cpp
// 2016/07/23 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2022/12/14 : Vitis HLS用に書き直した
// 2022/12/27 : 引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとガボール・フィルタ処理を選択できるようにした
// 2022/12/30 : user=1を待つdo while()文とmain()中のif文を削除した
//

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "Gabor_Filter_lh_3.h"

int conv_rgb2y(int rgb);

int Gabor_Filter_lh_3(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL,
        int32_t row_size, int32_t col_size, int32_t function){
#pragma HLS INTERFACE mode=s_axilite port=function
#pragma HLS INTERFACE mode=s_axilite port=col_size
#pragma HLS INTERFACE mode=s_axilite port=row_size
#pragma HLS INTERFACE mode=ap_none port=RorL
#pragma HLS INTERFACE mode=axis register_mode=both port=ins register
#pragma HLS INTERFACE mode=axis register_mode=both port=outs register
#pragma HLS INTERFACE mode=s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    ap_int<32> line_buf[ARRAY_SIZE-1][1920]; // Up to HD resolution
#pragma HLS array_partition variable=line_buf block factor=9 dim=1

    ap_int<32> pix_mat[ARRAY_SIZE][ARRAY_SIZE];
    int gray_pix, val, i, j, x, y, k;

    LOOP_LR: for (k=0; k<2; k++){
        LOOP_Y: for (y=0; y<row_size; y++){
#pragma HLS LOOP_TRIPCOUNT avg=600 max=1080 min=48
            LOOP_X: for (x=0; x<col_size; x++){
#pragma HLS LOOP_TRIPCOUNT avg=800 max=1920 min=64
#pragma HLS PIPELINE II=1
                ins >> pix;    // AXI4-Stream からの入力

                LOOP_PIX_MAT_K: for(int k=0; k<ARRAY_SIZE; k++){
                    LOOP_PIX_MAT_M: for(int m=0; m<ARRAY_SIZE-1; m++){
                        pix_mat[k][m] = pix_mat[k][m+1];
                    }
                }
                for (i=0; i<ARRAY_SIZE-1; i++){
                    pix_mat[i][ARRAY_SIZE-1] = line_buf[i][x];
                }
                ap_int<32> y_val = conv_rgb2y(pix.data);
                pix_mat[ARRAY_SIZE-1][ARRAY_SIZE-1] = y_val;

                for (i=0; i<ARRAY_SIZE-2; i++){    // 行の入れ替え
                    line_buf[i][x] = line_buf[i+1][x];
                }
                line_buf[ARRAY_SIZE-2][x] = y_val;

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = L_R_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE; j++){
                    for (i=0; i<ARRAY_SIZE; i++){
                        val += gabor_weight[ano][j][i] * pix_mat[j][i];
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                if(function == Gabor_Filter)
                    gabor.data = (val<<16)+(val<<8)+val;
                else
                    gabor.data = pix.data;

                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1)){
                    if(function == Gabor_Filter)
                        gabor.data = 0;
                }

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (col_size-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

  1. 2022年12月30日 15:50 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

AXI4-Stream 32 ビット入出力のガボール・フィルタを変更する1

Vitis HLS 2022.2 を使用して、AXI4-Stream 32 ビット入出力のガボール・フィルタ Gabor_Filter_lh_2 を Gabor_Filter_lh_3 として作成することにした。
Gabor_Filter_lh_3 はスルー出力とガボール・フィルタ出力を切り替えることができて、画像の大きさを指定することができるようにする。

Gabor_Filter_lh_3 のソースコードを貼っておく。
まずは、bmp_header.h だが、これはおなじみなのでリンクを貼っておく。
bmp_header.h は”AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作る1”に貼ってある。

Gabor_filter_lh_3.h を示す。

// Gabor_filter_lh_3.h
// 2016/07/24
// 2016/07/25 : 右白線検出用のGabor Filterの重みを追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2022/12/27 : 引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとガボール・フィルタ処理を選択できるようにした
//

#ifndef __Gabor_filter_lh_H__
#define __Gabor_filter_lh_H__

#define ARRAY_SIZE  9

#define RIGHT_WEIGHT    1
#define LEFT_WEIGHT     0
#define L_R_WEIGHT      2

#define Through         0
#define Gabor_Filter    1

const int gabor_weight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用
    {
        {0,-3,-10,-16,-7,7,10,5,1},
        {-3,-15,-27,-11,32,50,29,5,-2},
        {-11,-24,-5,73,135,95,16,-17,-10},
        {-11,4,85,187,160,14,-72,-52,-14},
        {4,51,135,137,-18,-159,-136,-45,-2},
        {16,50,59,-39,-179,-185,-73,3,13},
        {10,12,-25,-104,-131,-60,15,27,11},
        {1,-7,-31,-48,-24,18,29,14,3},
        {-1,-5,-9,-4,10,16,10,2,-1}
    },
    {
        {1,5,7,1,-12,-17,-10,-3,0},
        {1,11,33,45,21,-16,-27,-15,-4},
        {-8,-5,35,107,131,69,-2,-21,-11},
        {-17,-47,-51,40,169,187,93,13,-7},
        {-8,-54,-134,-147,-18,123,130,58,11},
        {9,-6,-82,-185,-187,-65,36,44,17},
        {11,24,12,-55,-125,-112,-43,1,7},
        {3,14,30,23,-13,-41,-33,-12,-1},
        {0,2,9,17,14,1,-6,-5,-2}
    }
};
const float gabor_fweight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用(float)
    {
        {0.001282,-0.009914,-0.04062,-0.060586,-0.027574,0.026072,0.038427,0.018191,0.003056},
        {-0.012155,-0.057448,-0.104645,-0.042953,0.123263,0.197238,0.114451,0.020448,-0.007239},
        {-0.042252,-0.093065,-0.018911,0.285374,0.525746,0.372687,0.060734,-0.064748,-0.040465},
        {-0.042261,0.015673,0.332798,0.728763,0.625046,0.053591,-0.283076,-0.203293,-0.05608},
        {0.017342,0.198305,0.52554,0.535526,-0.069756,-0.622839,-0.531089,-0.177366,-0.006367},
        {0.060866,0.19708,0.231032,-0.154219,-0.699885,-0.721808,-0.286707,0.013004,0.049249},
        {0.038379,0.04877,-0.098477,-0.404993,-0.510165,-0.233566,0.057894,0.104366,0.041887},
        {0.0047,-0.0278,-0.121277,-0.187262,-0.093276,0.070512,0.113857,0.055799,0.009976},
        {-0.003798,-0.01885,-0.035607,-0.01709,0.037692,0.064268,0.038606,0.007536,-0.002133}
    },
    {
        {0.005562,0.018882,0.028293,0.004499,-0.044995,-0.064838,-0.039469,-0.009822,0.000815},
        {0.002294,0.04108,0.127023,0.175094,0.083025,-0.063755,-0.106402,-0.057798,-0.01406},
        {-0.031269,-0.021096,0.135641,0.417286,0.512467,0.269946,-0.008354,-0.082091,-0.041357},
        {-0.066348,-0.184919,-0.197802,0.15614,0.65976,0.728616,0.361674,0.052074,-0.027152},
        {-0.031146,-0.211178,-0.523777,-0.573856,-0.069756,0.480311,0.506451,0.225223,0.041031},
        {0.035552,-0.023892,-0.320104,-0.723563,-0.728735,-0.253689,0.1391,0.170625,0.067723},
        {0.04216,0.094939,0.047511,-0.216623,-0.488075,-0.437898,-0.168739,0.003336,0.027009},
        {0.012112,0.056596,0.115239,0.090332,-0.05076,-0.158403,-0.127847,-0.046375,-0.004918},
        {-0.00168,0.007437,0.036985,0.067021,0.053689,0.004977,-0.02365,-0.018248,-0.005928}
    }
};

#endif


Gabor_Filter_lh_3.cpp を示す。

// Gabor_Filter_lh_3.cpp
// 2016/07/23 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2022/12/14 : Vitis HLS用に書き直した
// 2022/12/27 : 引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとガボール・フィルタ処理を選択できるようにした
//

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "Gabor_Filter_lh_3.h"

int conv_rgb2y(int rgb);

int Gabor_Filter_lh_3(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL,
        int32_t row_size, int32_t col_size, int32_t function){
#pragma HLS INTERFACE mode=s_axilite port=function
#pragma HLS INTERFACE mode=s_axilite port=col_size
#pragma HLS INTERFACE mode=s_axilite port=row_size
#pragma HLS INTERFACE mode=ap_none port=RorL
#pragma HLS INTERFACE mode=axis register_mode=both port=ins register
#pragma HLS INTERFACE mode=axis register_mode=both port=outs register
#pragma HLS INTERFACE mode=s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    ap_int<32> line_buf[ARRAY_SIZE-1][1920]; // Up to HD resolution
#pragma HLS array_partition variable=line_buf block factor=9 dim=1

    ap_int<32> pix_mat[ARRAY_SIZE][ARRAY_SIZE];
    int gray_pix, val, i, j, x, y, k;

    LOOP_WAIT_USER: do {
#pragma HLS LOOP_TRIPCOUNT avg=1 max=1 min=1
    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    LOOP_LR: for (k=0; k<2; k++){
        LOOP_Y: for (y=0; y<row_size; y++){
#pragma HLS LOOP_TRIPCOUNT avg=600 max=1080 min=48
            LOOP_X: for (x=0; x<col_size; x++){
#pragma HLS LOOP_TRIPCOUNT avg=800 max=1920 min=64
#pragma HLS PIPELINE II=1
                if (!(k==0 && x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                LOOP_PIX_MAT_K: for(int k=0; k<ARRAY_SIZE; k++){
                    LOOP_PIX_MAT_M: for(int m=0; m<ARRAY_SIZE-1; m++){
                        pix_mat[k][m] = pix_mat[k][m+1];
                    }
                }
                for (i=0; i<ARRAY_SIZE-1; i++){
                    pix_mat[i][ARRAY_SIZE-1] = line_buf[i][x];
                }
                ap_int<32> y_val = conv_rgb2y(pix.data);
                pix_mat[ARRAY_SIZE-1][ARRAY_SIZE-1] = y_val;

                for (i=0; i<ARRAY_SIZE-2; i++){    // 行の入れ替え
                    line_buf[i][x] = line_buf[i+1][x];
                }
                line_buf[ARRAY_SIZE-2][x] = y_val;

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = L_R_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE; j++){
                    for (i=0; i<ARRAY_SIZE; i++){
                        val += gabor_weight[ano][j][i] * pix_mat[j][i];
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                if(function == Gabor_Filter)
                    gabor.data = (val<<16)+(val<<8)+val;
                else
                    gabor.data = pix.data;

                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1)){
                    if(function == Gabor_Filter)
                        gabor.data = 0;
                }

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (col_size-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


Gabor_Filter_lh_3_tb.cpp を示す。

// Gabor_Filter_lh_3_tb.cpp
// 2016/07/24 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2022/12/14 : Vitis HLS用に書き直した
// 2022/12/27 : 引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとガボール・フィルタ処理を選択できるようにした
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <ap_axi_sdata.h>

#include "Gabor_Filter_lh_3.h"
#include "bmp_header.h"

int Gabor_Filter_lh_3(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL,
        int32_t row_size, int32_t col_size, int32_t function);

int conv_rgb2y_soft(int rgb);
int Gabor_Filter_lh_3_soft(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL,
        int32_t row_size, int32_t col_size, int32_t function);

#define CLOCK_PERIOD 10
#define RIGHT_OR_LEFT   L_R_WEIGHT
#define BMP_FILE_NAME   "test.bmp"

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > ins, ins2;
    hls::stream<ap_axis<32,1,1,1> > ins_soft;
    hls::stream<ap_axis<32,1,1,1> > outs, outs2;
    hls::stream<ap_axis<32,1,1,1> > outs_soft;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals;
    ap_axis<32,1,1,1> vals_soft;

    int m_seq = 1; // M系列の値
    int i, k;
    int xor_shift;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw, *fbmpwf;
    int *rd_bmp, *hw_gabor, *sw_gabor;
    int blue, green, red;
    ap_uint<2> r_l;
    char fhname[100];
    char fsname[100];

    if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    printf("bmpihr.biWidth = %d, bmpihr.biHeight = %d\n",(int)bmpihr.biWidth, (int)bmpihr.biHeight);
    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }
    if ((sw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // 2画面分を入力する
    for(int k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];

                if (j==0 && i==0)    // 最初のデータの時に TUSER を 1 にする
                    pix.user = 1;
                else
                    pix.user = 0;

                if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
                    pix.last = 1;
                else
                    pix.last = 0;

                ins << pix;
                ins2 << pix;
                ins_soft << pix;
            }
        }
    }

    r_l = (ap_uint<2>)RIGHT_OR_LEFT;
    Gabor_Filter_lh_3(ins, outs, r_l, 48, 64, Gabor_Filter);
    Gabor_Filter_lh_3_soft(ins_soft, outs_soft, r_l, 48, 64, Gabor_Filter);

    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    for(k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                outs >> vals;
                outs_soft >> vals_soft;
                ap_int<32> val = vals.data;
                ap_int<32> val_soft = vals_soft.data;

                hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val;
                sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val_soft;

                //printf("k=%d, j=%d, i=%d\n",k,j,i);
                if ((double)pow((double)(val&0xff)-(val_soft&0xff),(double)2) > 4){ // 2乗誤差が4よりも大きい
                    printf("ERROR HW and SW results mismatch i = %ld, j = %ld, HW = %08x, SW = %08x\n", i, j, (int)val, (int)val_soft);
                    //return(1);
                }
                //if (vals.last)
                    //cout << "AXI-Stream is end" << endl;
            }
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    // ハードウェアのラプラシアンフィルタの結果を temp_gabor0.bmp, temp_gabor1.bmp へ出力する
    for(k=0; k<2; k++){
        if(k == 0){
            if ((fbmpw=fopen("temp_gabor0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpw=fopen("temp_gabor1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpw);
                fputc(green, fbmpw);
                fputc(red, fbmpw);
            }
        }
        fclose(fbmpw);
    }

    // 元画像を出力
    Gabor_Filter_lh_3(ins2, outs2, r_l, 48, 64, Through);

    // hw_gabor[]に画像を出力
    for(k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                outs2 >> vals;
                ap_int<32> val = vals.data;

                hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val;
            }
        }
    }

    // ハードウェアのラプラシアンフィルタの結果を temp_gabor0.bmp, temp_gabor1.bmp へ出力する
    for(k=0; k<2; k++){
        if(k == 0){
            if ((fbmpw=fopen("temp_org0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_org0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpw=fopen("temp_org1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_org1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpw);
                fputc(green, fbmpw);
                fputc(red, fbmpw);
            }
        }
        fclose(fbmpw);
    }

    // ソフトウェアのラプラシアンフィルタの結果を temp_gabor_float0.bmp, temp_gabor_float1.bmp へ出力する
    for(k=0; k<2; k++){
        if (k == 0){
            if ((fbmpwf=fopen("temp_gabor_float0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpwf=fopen("temp_gabor_float1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpwf);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpwf);
                fputc(green, fbmpwf);
                fputc(red, fbmpwf);
            }
        }
        fclose(fbmpwf);
    }

    free(rd_bmp);
    free(hw_gabor);

    return 0;
}

int Gabor_Filter_lh_3_soft(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL,
        int32_t row_size, int32_t col_size, int32_t function){
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    ap_int<32> line_buf[ARRAY_SIZE-1][1920]; // Up to HD resolution
    ap_int<32> pix_mat[ARRAY_SIZE][ARRAY_SIZE];
    int gray_pix, val, i, j, x, y, k;

    do {
    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (k=0; k<2; k++){
        for (y=0; y<row_size; y++){
            for (x=0; x<col_size; x++){
                if (!(k==0 && x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                LOOP_PIX_MAT_K: for(int k=0; k<ARRAY_SIZE; k++){
                    LOOP_PIX_MAT_M: for(int m=0; m<ARRAY_SIZE-1; m++){
                        pix_mat[k][m] = pix_mat[k][m+1];
                    }
                }
                for (i=0; i<ARRAY_SIZE-1; i++){
                    pix_mat[i][ARRAY_SIZE-1] = line_buf[i][x];
                }
                ap_int<32> y_val = conv_rgb2y_soft(pix.data);
                pix_mat[ARRAY_SIZE-1][ARRAY_SIZE-1] = y_val;

                for (i=0; i<ARRAY_SIZE-2; i++){    // 行の入れ替え
                    line_buf[i][x] = line_buf[i+1][x];
                }
                line_buf[ARRAY_SIZE-2][x] = y_val;

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = L_R_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE; j++){
                    for (i=0; i<ARRAY_SIZE; i++){
                        val += gabor_weight[ano][j][i] * pix_mat[j][i];
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                if(function == Gabor_Filter)
                    gabor.data = (val<<16)+(val<<8)+val;
                else
                    gabor.data = pix.data;

                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1)){
                    if(function == Gabor_Filter)
                        gabor.data = 0;
                }

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (col_size-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


Vitis HLS 2022.2 の Gabor_Filter_lh_3 プロジェクトを示す。
Zybot2_62_221229.png
  1. 2022年12月29日 05:09 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作る2

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作る1”の続き。

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作って、ガボール・フィルタの後に入れて値を確認してみようと思うということで、前回は、ソースコードを貼った。今回は、C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL、Implementation を行った。

C シミュレーションを行った。結果を示す。
Zybot2_54_221227.png

lap_filter_axis/solution/csim/build ディレクトリを示す。
temp_lap_bmp がラプラシアン・フィルタ処理結果となる。
Zybot2_61_221228.png

C コードの合成結果を示す。
Zybot2_55_221227.png
Zybot2_56_221227.png
Zybot2_57_221227.png

Latency も HD 解像度のピクセルの 2073600 からいくらも外れていないので、問題無さそうだ。

C/RTL 協調シミュレーションを行った。結果を示す。
Zybot2_58_221227.png

Max Latency は 3095 クロックで、64 x 48 ピクセルの 3072 から余り外れていない。

C/RTL 協調シミュレーションの波形を確認してみよう。
Zybot2_59_221227.png

ins_TREDY や outs_TVALID がほとんど 1 になっていることが分かる。

Export RTL を行った。
IP が生成された。

Implementation を行った。結果を示す。
Zybot2_60_221227.png

CP achieved post-implementation が 9.249 ns で問題無さそうだ。
  1. 2022年12月28日 05:22 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作る1

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタを作って、ガボール・フィルタの後に入れて値を確認してみようと思う。家で白線をガボール・フィルタ処理してみたところ、0xff が複数ピクセルに渡って現れることが分かった。それのエッジを取ってみようという発想だ。上昇する方のエッジのみを使用するので、マイナスの方は 0 にしようと思う。

AXI4-Stream 32 ビット入出力のラプラシアン・フィルタの bmp_header.h を示す。

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType; 
    uint32_t bfSize; 
    uint16_t bfReserved1; 
    uint16_t bfReserved2; 
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize; 
    int32_t biWidth; 
    int32_t biHeight; 
    uint16_t biPlanes; 
    uint16_t biBitCount; 
    uint32_t biCompression; 
    uint32_t biSizeImage; 
    int32_t biXPixPerMeter; 
    int32_t biYPixPerMeter; 
    uint32_t biClrUsed; 
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} BMP24FORMAT;


lap_filter_axis.h を示す。

// lap_filter_axis.h
// 2015/05/01
// 2022/12/26 : modified by marsee

// function value
#define Through  0
#define Lap_Filter 1


lap_filter_axis.cpp を示す。

//
// lap_filter_axis.cpp
// by marsee
// 2015/05/01
// 2015/06/25 : 修正、ラプラシアンフィルタの値が青だけになっていたので、RGBに拡張した
// 2022/12/27 : 修正、Vitis_HLS 2022.2用に変更、引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとラプラシアン・フィルタ処理を選択できるようにした
//

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "lap_filter_axis.h"

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axis(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs,
        uint32_t row_size, uint32_t col_size, uint32_t function){
#pragma HLS INTERFACE mode=s_axilite port=function
#pragma HLS INTERFACE mode=s_axilite port=col_size
#pragma HLS INTERFACE mode=s_axilite port=row_size
#pragma HLS INTERFACE mode=axis register_mode=both port=ins register
#pragma HLS INTERFACE mode=axis register_mode=both port=outs register
#pragma HLS INTERFACE mode=s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> lap;

    unsigned int line_buf[2][1920];
#pragma HLS array_partition variable=line_buf block factor=2 dim=1

    int pix_mat[3][3];
#pragma HLS array_partition variable=pix_mat complete

    int lap_fil_val;

    Loop1 : do {    // user が 1になった時にフレームがスタートする
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
        ins >> pix;
    } while(pix.user == 0);

    Loop2 : for (int y=0; y<row_size; y++){
#pragma HLS LOOP_TRIPCOUNT avg=600 max=1080 min=48
        Loop3 : for (int x=0; x<col_size; x++){
#pragma HLS LOOP_TRIPCOUNT avg=800 max=1920 min=64
#pragma HLS PIPELINE II=1
            if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                ins >> pix; // AXI4-Stream からの入力

            Loop4 : for (int k=0; k<3; k++){
                Loop5 : for (int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];

            int y_val = conv_rgb2y(pix.data);
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            lap_fil_val = laplacian_fil(    pix_mat[0][0], pix_mat[0][1], pix_mat[0][2],
                                        pix_mat[1][0], pix_mat[1][1], pix_mat[1][2], 
                                        pix_mat[2][0], pix_mat[2][1], pix_mat[2][2]);
            if(function == Lap_Filter)
                lap.data = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
            else
                lap.data = pix.data; // 元画像

            if (x<2 || y<2){ // 最初の2行とその他の行の最初の2列は無効データなので0とする
                if(function == Lap_Filter)
                    lap.data = 0;
            }

            if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                lap.user = 1;
            else
                lap.user = 0;
            
            if (x == (col_size-1))  // 行の最後で TLAST をアサートする
                lap.last = 1;
            else
                lap.last = 0;

            outs << lap;    // AXI4-Stream へ出力
        }
    }

    return 0;
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0; // マイナスのエッジは0とする
        // y = -y; // マイナスエッジを有効にする
    else if (y>255)
        y = 255;
    return(y);
}


lap_filter_axis_tb.cpp を示す。

// lap_filter_axis_tb.cpp
// by marsee
// 2015/05/01
// 2015/08/17 : BMPファイルを読み書きするように変更した
// 2022/12/27 : 修正、Vitis_HLS 2022.2用に変更、引数にrow_size, col_size, functionを追加
//              functionの値で元画像をスルーとラプラシアン・フィルタ処理を選択できるようにした
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <ap_axi_sdata.h>

#include "lap_filter_axis.h"
#include "bmp_header.h"

int lap_filter_axis(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs,
        uint32_t row_size, uint32_t col_size, uint32_t function);

int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y_soft(int rgb);
int lap_filter_axis_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, int width, int height);

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > ins, ins2;
    hls::stream<ap_axis<32,1,1,1> > ins_soft;
    hls::stream<ap_axis<32,1,1,1> > outs, outs2;
    hls::stream<ap_axis<32,1,1,1> > outs_soft;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals;
    ap_axis<32,1,1,1> vals_soft;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw;
    int *rd_bmp, *hw_lapd;
    int blue, green, red;

    if ((fbmpr = fopen("test.bmp", "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_lapd =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_lapd memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // ins に入力データを用意する
    for(int i=0; i<5; i++){ // dummy data
        pix.user = 0;
        pix.data = i;
        ins << pix;
    }

    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];

            if (j==0 && i==0)   // 最初のデータの時に TUSER を 1 にする
                pix.user = 1;
            else
                pix.user = 0;

            if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
                pix.last = 1;
            else
                pix.last = 0;

            ins << pix;
            ins2 << pix;
            ins_soft << pix;
        }
    }

    lap_filter_axis(ins, outs, bmpihr.biHeight, bmpihr.biWidth, Lap_Filter);
    lap_filter_axis_soft(ins_soft, outs_soft, bmpihr.biWidth, bmpihr.biHeight);

    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    cout << endl;
    cout << "outs" << endl;
    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            outs >> vals;
            outs_soft >> vals_soft;
            ap_int<32> val = vals.data;
            ap_int<32> val_soft = vals_soft.data;

            hw_lapd[(j*bmpihr.biWidth)+i] = (int)val;

            if (val != val_soft){
                printf("ERROR HW and SW results mismatch i = %ld, j = %ld, HW = %d, SW = %d\n", i, j, (int)val, (int)val_soft);
                return(1);
            }
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    // ハードウェアのラプラシアンフィルタの結果を temp_lap.bmp へ出力する
    if ((fbmpw=fopen("temp_lap.bmp", "wb")) == NULL){
        fprintf(stderr, "Can't open temp_lap.bmp by binary write mode\n");
        exit(1);
    }
    // BMPファイルヘッダの書き込み
    fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

    // RGB データの書き込み、逆順にする
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
            green = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
            red = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

            fputc(blue, fbmpw);
            fputc(green, fbmpw);
            fputc(red, fbmpw);
        }
    }
    fclose(fbmpw);

    // 元画像のスルーパスをテスト
    lap_filter_axis(ins2, outs2, bmpihr.biHeight, bmpihr.biWidth, Through);

    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            outs2 >> vals;
            ap_int<32> val = vals.data;
            hw_lapd[(j*bmpihr.biWidth)+i] = (int)val;
        }
    }
    // 元画像の出力結果を temp_org.bmp へ出力する
    if ((fbmpw=fopen("temp_org.bmp", "wb")) == NULL){
        fprintf(stderr, "Can't open temp_org.bmp by binary write mode\n");
        exit(1);
    }
    // BMPファイルヘッダの書き込み
    fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

    // RGB データの書き込み、逆順にする
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
            green = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
            red = (hw_lapd[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

            fputc(blue, fbmpw);
            fputc(green, fbmpw);
            fputc(red, fbmpw);
        }
    }
    fclose(fbmpw);
    free(rd_bmp);
    free(hw_lapd);

    return 0;
}

int lap_filter_axis_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, int width, int height){
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> lap;
    unsigned int **line_buf;
    int pix_mat[3][3];
    int lap_fil_val;
    int i;

    // line_buf の1次元目の配列をアロケートする
    if ((line_buf =(unsigned int **)malloc(sizeof(unsigned int *) * 2)) == NULL){
        fprintf(stderr, "Can't allocate line_buf[3][]\n");
        exit(1);
    }

    // メモリをアロケートする
    for (i=0; i<2; i++){
        if ((line_buf[i]=(unsigned int *)malloc(sizeof(unsigned int) * width)) == NULL){
            fprintf(stderr, "Can't allocate line_buf[%d]\n", i);
            exit(1);
        }
    }

    do {    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (int y=0; y<height; y++){
        for (int x=0; x<width; x++){
            if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                ins >> pix; // AXI4-Stream からの入力

            for (int k=0; k<3; k++){
                for (int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];

            int y_val = conv_rgb2y_soft(pix.data);
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            lap_fil_val = laplacian_fil_soft(    pix_mat[0][0], pix_mat[0][1], pix_mat[0][2],
                                        pix_mat[1][0], pix_mat[1][1], pix_mat[1][2], 
                                        pix_mat[2][0], pix_mat[2][1], pix_mat[2][2]);
            lap.data = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる

            if (x<2 || y<2) // 最初の2行とその他の行の最初の2列は無効データなので0とする
                lap.data = 0;

            if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                lap.user = 1;
            else
                lap.user = 0;
            
            if (x == (width-1))    // 行の最後で TLAST をアサートする
                lap.last = 1;
            else
                lap.last = 0;

            outs << lap;    // AXI4-Stream へ出力
        }
    }

    for (i=0; i<2; i++)
        free(line_buf[i]);
    free(line_buf);

    return 0;
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


Vitis HLS 2022.2 の lap_filter_axis プロジェクトを示す。
Zybot2_52_221227.png

/media/masaaki/Ubuntu_Disk/Vitis_HLS/ZYBO/2022.2/lap_filter_axis ディレクトリを示す。
Zybot2_53_221227.png
  1. 2022年12月27日 04:20 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋のまとめサイトの更新(2022年12月26日)

FPGAの部屋のまとめサイトを更新しました。
KR260 カテゴリを追加して、その他の記事をまとめました。
  1. 2022年12月26日 03:22 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する9(白線コースでデータ収集)

Zybot でガボール・フィルタを使用して白線間走行する8(BTN0 への変更とソフトウェアの修正)”の続き。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、この ZYBO 個体の SW4 がおかしいので、BTN0 に変更した。そして、Vivado を論理合成、インプリメンテーション、ビットストリームの生成を行った。タイミング・エラーが発生したが無視することにした。Vitis でアプリケーション・ソフトウェアを変更した。今回は、実際のコースでデータを収集した。

コースに置いた Zybot の写真を示す。
Zybot2_48_221224.jpg

このような配置でのガボール・フィルタ結果を示す。
最初に左白線用パラメータのガボール・フィルタ画像を示す。(sw2 OFF)
Zybot2_49_221224.jpg

右白線用パラメータのガボール・フィルタ画像を示す。(sw2 ON)
Zybot2_50_221224.jpg

右白線パラメータでは左白線も濃くでているように写真が取れているが、目で見た場合には左白線は多少薄くなっている。

sw0 を ON にして DEBUG モードにすると判定が”Left turn”に固定されている。Zybot を降って白線の見え方を変えても変わらなかった。残念ながらターミナル画面をキャプチャするのを忘れてしまった。

原因を追求するために BTN0 を押して、ガボール・フィルタ結果をキャプチャした。
左白線パラメータでのガボール・フィルタのデータを示す。
Zybot2_39_221223.png

右白線パラメータでのガボール・フィルタのデータを示す。
Zybot2_40_221223.png

シリアル・ターミナルでは、一部のデータしか見ることができないので、cu コマンドでファイルに保存した。
最初に /ttyUSB1 の権限を変更した。
sudo chmod o+wr /dev/ttyUSB1

左白線パラメータでのガボール・フィルタのデータを
cu -s 115200 -l /dev/ttyUSB1 > gabor_left1_221223.txt
で取得した。
右白線パラメータでのガボール・フィルタのデータを
cu -s 115200 -l /dev/ttyUSB1 > gabor_right1_221223.txt
で取得した。
(2023/01/07:追記) cu を終了する時のコマンドは
~.
Zybot2_41_221223.png

gabor_left1_221223.txt と gabor_right1_221223.txt が生成された。
Zybot2_42_221223.png

gabor_left1_221223.txt を示す。
Zybot2_43_221223.png

gabor_right1_221223.txt を示す。
Zybot2_44_221223.png

gabor_left1_221223.txt と gabor_right1_221223.txt の下の部分を見たところ、0xff が連続していて思ったよりも多いことが分かった。
0xff などの固定された値以上が最初に現れた部分を見つけるといったアルゴリズムでは、このコースでは問題があるようだ。
Zybot2_51_221224.png

もう一度、白線を検出するアルゴリズムを見直してみたい。
白線を検出している部分でのデータを所得するを忘れていた。これを取得したい。
ファイルにしたガボール・フィルタのデータを画像にしてみたい。
  1. 2022年12月24日 05:25 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する8(BTN0 への変更とソフトウェアの修正)

Zybot でガボール・フィルタを使用して白線間走行する7(Vivado で スイッチ を 4 個実装)”の続き。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、Motor OFF と Debug 表示をスライドスイッチで設定するために axi_gpio_0 を 1 ビット入力から 4 ビット入力に変更した。今回は、この ZYBO 個体の SW4 がおかしいので、BTN0 に変更した。そして、Vivado を論理合成、インプリメンテーション、ビットストリームの生成を行った。タイミング・エラーが発生したが無視することにした。Vitis でアプリケーション・ソフトウェアを変更した。

どうも SW4 の調子がおかしい。具体的には、最初に 0 にしていても 1 に認識されてしまうという不具合があったので、SW4 だけをBTN0 にアサインすることにした。
制約ファイルの ZYBOt.xdc の最後の行を以下のように変更した。

set_property PACKAGE_PIN R18 [get_ports {sw[3]}] # BTN0


Zybot2_45_221223.png

これで、論理合成、インプリメンテーション、ビットストリームの生成を行ったところ、タイミング・エラーが発生した。
Zybot2_46_221223.png

Implementation Design を開いて見たところ、タイミング・エラーはラプラシアン・フィルタ周辺で起きていたので、無視することにした。
Zybot2_47_221223.png

ハードウェアをエクスポートして、Vitis の ZYBOt_wrapper プラットフォームを Update Hardware Specfication した。

アプリケーション・ソフトウェアの wl_tarcking_gabor_bm.c も SW や BTN0 で機能を追加するために変更した。
SW と BTN0 の機能を示す。

sw0 - 0 : NORMAL, 1 : DEBUG
sw1 - 0 : MOTOR OFF, 1 : MOTOR ON
sw2 - 0 : 左白線用のパラメータでガボール・フィルタさせた画像をディスプレイに表示する
sw2 - 1 : 右白線用のパラメータでガボール・フィルタさせた画像をディスプレイに表示する
BTN0 - 1 : sw2 で示された SVGA 画面分のガボール・フィルタの値を標準出力に出力する


Zybot2_38_221223.png

現在の wl_tarcking_gabor_bm.c を貼っておく。

// wl_tracking_gabor_bm.c
// 2022/12/18 : by marsee
// 2022/12/21 : bug fix. by marsee
// 2022/12/23 : Added sw2, BTN0.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "sleep.h"

#include "xparameters.h"
#include "xil_io.h"
#include "xpwm.h"
#include "xmotor_monitor.h"

#define DIR_LEFT_NORMAL        1
#define DIR_LEFT_REVERSE    0
#define DIR_RIGHT_NORMAL    0
#define DIR_RIGHT_REVERSE    1

#define PIXEL_NUM_OF_BYTES    4
#define SVGA_HORIZONTAL_PIXELS  800
#define SVGA_VERTICAL_LINES     600
#define SVGA_ALL_DISP_ADDRESS   (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)

#define GABOR_DETECT_LINE        590
#define GABOR_DETECT_LINE_ADDR    (SVGA_HORIZONTAL_PIXELS * GABOR_DETECT_LINE * PIXEL_NUM_OF_BYTES)
#define GABOR_THRESHOLD            255
#define DIST_THRESHOLD            30

#define LEFT_GABOR_EDGE_OVERFLOW    0
#define RIGHT_GABOR_EDGE_OVERFLOW    (SVGA_HORIZONTAL_PIXELS/2)

//#define DEBUG
//#define MOTOR_OFF

#define FRAME_BUFFER_ADDRESS    0x10000000

#define GABOR_LEFT  0
#define GABOR_RIGHT 1

void cam_i2c_init(volatile uint32_t *mt9d111_axi_iic) {
    mt9d111_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
    mt9d111_axi_iic[64] = 0x1; // enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
        // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile uint32_t *mt9d111_axi_iic, uint32_t device_addr, uint32_t write_addr, uint32_t write_data){
    mt9d111_axi_iic[66] = 0x100 | (device_addr & 0xfe);    // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    mt9d111_axi_iic[66] = write_addr;
    mt9d111_axi_iic[66] = (write_data >> 8)|0xff;            // first data
    mt9d111_axi_iic[66] = 0x200 | (write_data & 0xff);        // second data
    cam_i2x_write_sync();
}

// Gobor filter
//
void gabor_fil_on(){
    volatile uint32_t *axis_switch_0, *axis_switch_1;
    volatile uint32_t *gabor_filter_lh_0;

    axis_switch_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR;
    axis_switch_1 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR;
    gabor_filter_lh_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_GABOR_FILTER_LH_2_0_S_AXI_CONTROL_BASEADDR;

    // axis_switch_1, 1to2 ,Select M01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_1[16] = 0x80000000; // 0x40 = 0x80000000; axi_switch_0 M00_AXIS disable
    axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000; axi_switch_0 M01_AXIS disable
    axis_switch_1[18] = 0x80000000; // 0x48 = 0x80000000; axi_switch_0 M02_AXIS disable
    axis_switch_1[19] = 0x80000000; // 0x4C = 0x80000000; axi_switch_0 M03_AXIS disable
    axis_switch_1[20] = 0; // 0x50 = 0; axi_switch_4 M00_AXIS enable. gabor fitler
    axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers

    // gabor filter AXIS Start
    gabor_filter_lh_0[0] = 0x01; // Start bit set
    gabor_filter_lh_0[0] = 0x80; // Auto Restart bit set

    // axis_switch_0, 2to1, Select S01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_0[16] = 0x4; // 0x40 = 0x4; gabor fitler
    axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
}

int search_gabor_edge(uint32_t start_addr, uint32_t number, uint32_t threshold){
    volatile uint32_t *imgaddr;
    int i;

    imgaddr = (volatile uint32_t *)start_addr;
    //printf("start_addr = %x\n", (int)start_addr);

    for (i=0; i<number; i++){
        uint32_t c=imgaddr[i] & 0xff;
        //printf("%d, %d, %d\n",(int)number, i, (int)c);
        if (c >= threshold){
            break;
        }
    }
    return(i);
}

// Motor
//
void motor_settings(XPwm *motorLp, XPwm *motorRp){
    XPwm_DisableAutoRestart(motorLp);
    while(!XPwm_IsIdle(motorLp)) ;
    XPwm_Start(motorLp);
    XPwm_EnableAutoRestart(motorLp);

    XPwm_DisableAutoRestart(motorRp);
    while(!XPwm_IsIdle(motorRp)) ;
    XPwm_Start(motorRp);
    XPwm_EnableAutoRestart(motorRp);
}

void Stopped_Zybot(XPwm *motorLp, XPwm *motorRp){
    XPwm_Set_sw_late_V(motorLp, 0);
    XPwm_Set_sw_late_V(motorRp, 0);
}

void motor_initialize(XPwm *motorL, XPwm *motorR, XMotor_monitor *mmL, XMotor_monitor *mmR){
    XPwm *motorLp, *motorRp;
    XMotor_monitor *mmLp, *mmRp;

    motorLp = motorL;
    motorRp = motorR;
    mmLp = mmL;
    mmRp = mmR;

    // Initialization of motor
    if (XPwm_Initialize(motorLp, 0) != XST_SUCCESS){
        fprintf(stderr,"pwm_0 (Left) open error\n");
        exit(-1);
    }
    if (XPwm_Initialize(motorRp, 1) != XST_SUCCESS){
        fprintf(stderr,"pwm_1 (Right) open error\n");
        exit(-1);
    }

    // Initialization of motor monitor
    if (XMotor_monitor_Initialize(mmLp, 0) != XST_SUCCESS){
        fprintf(stderr,"motor_monitor_0 (Left) open error\n");
        exit(-1);
    }
    if (XMotor_monitor_Initialize(mmRp, 1) != XST_SUCCESS){
        fprintf(stderr,"motor_monitor_1 (Right) open error\n");
        exit(-1);
    }

    // The Motors is rotated in the forward direction.
    XPwm_Set_sw_late_V(motorLp, 0);
    XPwm_Set_dir_V(motorLp, 1);

    XPwm_Set_sw_late_V(motorRp, 0);
    XPwm_Set_dir_V(motorRp, 0);

    motor_settings(motorLp, motorRp);
}

int check_debug(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    return(val & 1);
}

int check_motor_on(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    val = val>>1;
    return(val & 1);
}

int check_gabor_LR(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    val = val>>2;
    return(val & 1);
}

int check_gabor_display(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    val = val>>3;
    return(val & 1);
}

int gabor_data_disp(uint32_t fb_addr, uint32_t lr){
    volatile uint32_t *fb_addrp = (volatile uint32_t *)fb_addr;

    if(lr == GABOR_LEFT)
        printf("----- gabor left data -----\n");
    else
        printf("----- gabor right data -----\n");
    for(int i=0; i<SVGA_HORIZONTAL_PIXELS*SVGA_VERTICAL_LINES; i++){
        if((i%40) == 0)
            printf("\n");
        printf("%02x", (int)(fb_addrp[i] & 0xff));
    }
    printf("\n");
    return(0);
}

int main(){
    volatile uint32_t *dmaw4gabor_0;
    XPwm motorL, motorR;
    XMotor_monitor mmL, mmR;
    int left_wl_edge, right_wl_edge;
    volatile uint32_t *frame_buffer;
    // mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cntrler_axi_master_0
    volatile uint32_t *bmdc0_axi_lites;
    volatile uint32_t *mt9d111_axi_lites;
    volatile uint32_t *mt9d111_i2c_axi_lites;
    volatile uint32_t *axi_gpio_0;

    // axi_gpio_0 : sw0 - 0 : NORMAL, 1 : DEBUG
    //              sw1 - 0 : MOTOR OFF, 1 : MOTOR ON
    //              sw2 - 0 : Display the Gabor-filtered image for the left white line on the display
    //              sw2 - 1 : Display the Gabor-filtered image for the right white line on the display
    //              BTN0 - 1 : Display the value of the Gabor filter for one screen. sw2 designates right white line data or left white line data.
    axi_gpio_0 = (volatile uint32_t *)XPAR_AXI_GPIO_0_BASEADDR;

    // Motor Initialize
    motor_initialize(&motorL, &motorR, &mmL, &mmR);

    // DMAW4Gabor Initialize
    dmaw4gabor_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_DMAW4GABOR_0_S_AXI_AXILITES_BASEADDR;

    frame_buffer = (volatile uint32_t *)FRAME_BUFFER_ADDRESS;

    // DMA4Gabor frame_buffer setting
    dmaw4gabor_0[6] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Data signal of frame_buffer0
    dmaw4gabor_0[8] = (volatile uint32_t)FRAME_BUFFER_ADDRESS + (volatile uint32_t)SVGA_ALL_DISP_ADDRESS; // Data signal of frame_buffer1

    // Camera, display controller
    bmdc0_axi_lites = (volatile uint32_t *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
    mt9d111_axi_lites = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_MT9D111_INF_AXIS_0_BASEADDR;
    mt9d111_i2c_axi_lites = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXI_IIC_0_BASEADDR;

    // IP start
    dmaw4gabor_0[0] = (volatile uint32_t)0x81; // start, auto restart
    gabor_fil_on();
    bmdc0_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 0 start
    mt9d111_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Camera Interface start (Address is dummy)

    // CMOS Camera initialize, MT9D111
    cam_i2c_init(mt9d111_i2c_axi_lites);

    cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0xf0, 0x1);      // Changed regster map to IFP page 1
    cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0x97, 0x20);        // RGB Mode, RGB565

    mt9d111_axi_lites[1] = 0; // One_shot_mode is disabled

    // main loop
    if(check_debug(axi_gpio_0))
        printf("White line Tracking start. \n");

    while(1){
        // Gabor filter for left white line
        left_wl_edge = SVGA_HORIZONTAL_PIXELS/2 - search_gabor_edge(
                FRAME_BUFFER_ADDRESS+GABOR_DETECT_LINE_ADDR, SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);

        // Gabor filter for right white line
        right_wl_edge = search_gabor_edge(
                FRAME_BUFFER_ADDRESS+SVGA_ALL_DISP_ADDRESS+GABOR_DETECT_LINE_ADDR+(SVGA_HORIZONTAL_PIXELS/2)*PIXEL_NUM_OF_BYTES,
            SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);

        if(check_debug(axi_gpio_0))
            printf("left_wl_edge = %d, right_wl_edge = %d\n", left_wl_edge, right_wl_edge);

        if (left_wl_edge == LEFT_GABOR_EDGE_OVERFLOW){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 15);
                XPwm_Set_sw_late_V(&motorR, 45);
            }
            if(check_debug(axi_gpio_0))
                printf("Left gabor edge is overflow\n");

        } else if (right_wl_edge == RIGHT_GABOR_EDGE_OVERFLOW){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 45);
                XPwm_Set_sw_late_V(&motorR, 15);
            }
            if(check_debug(axi_gpio_0))
                printf("Right gabar edge is overflow\n");

        } else if ((right_wl_edge - left_wl_edge) > DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 35);
                XPwm_Set_sw_late_V(&motorR, 25);
            }
            if(check_debug(axi_gpio_0))
                printf("Right turn\n");

        } else if ((right_wl_edge - left_wl_edge) < -DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 25);
                XPwm_Set_sw_late_V(&motorR, 35);
            }
            if(check_debug(axi_gpio_0))
                printf("Left turn\n");

        } else if (abs(right_wl_edge - left_wl_edge) <= DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 30);
                XPwm_Set_sw_late_V(&motorR, 30);
            }
            if(check_debug(axi_gpio_0))
                printf("Go straight\n");
        }
        if(check_gabor_LR(axi_gpio_0)){
            bmdc0_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS + (volatile uint32_t)SVGA_ALL_DISP_ADDRESS; // right
        } else {
            bmdc0_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // left
        }
        if(check_gabor_display(axi_gpio_0)){
            if(check_gabor_LR(axi_gpio_0)){
                gabor_data_disp((uint32_t)FRAME_BUFFER_ADDRESS+(uint32_t)SVGA_ALL_DISP_ADDRESS, (uint32_t)GABOR_RIGHT);
            } else {
                gabor_data_disp((uint32_t)FRAME_BUFFER_ADDRESS, (uint32_t)GABOR_LEFT);
            }
        }
        if(!check_motor_on(axi_gpio_0)){ // sw1 off. Motor Stopped
            XPwm_Set_sw_late_V(&motorL, 0);
            XPwm_Set_sw_late_V(&motorR, 0);
        }
    }
}


  1. 2022年12月23日 05:05 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する7(Vivado で スイッチ を 4 個実装)

Zybot でガボール・フィルタを使用して白線間走行する6(Vitis 2022.2 でアプリケーション・ソフトを作成)”の続き。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、Vivado 2022.2 でハードウエアをエクスポートして、Vitis でプラットフォームとアプリケーション・ソフトウエアを作成しようとするが、まだ途中だった。今回は、Motor OFF と Debug 表示をスライドスイッチで設定するために axi_gpio_0 を 1 ビット入力から 4 ビット入力に変更した。

スライドスイッチが 1 個のみ axi_gpio_0 に入力ポートになっていたが、Motor OFF と Debug 表示をスライドスイッチで設定したいので、4 個のスライドスイッチを入力ポートとして、使用することにした。
SW0 が ON になると、DEBUG モードで標準出力に表示が出る。
SW1 が ON になると、Motor ON モードでモーターが回り、OFF だと Motor OFF でモーターは止まる。

axi_gpio_0 の入力の GPIO の GPIO Width を 4 に変更した。sw は sw[3:0] になったと思う。
Zybot2_34_221220.png

ZYBOt_i ブロック・デザインを示す。
Zybot2_32_221220.png
Zybot2_33_221220.png

論理合成、インプリメンテーション、ビットストリームの生成を行て成功した。結果を示す。
Zybot2_35_221220.png

ハードウエアをエクスポートした。

Vitis の ZYBOt_warpper プラットフォームで Update Hardware Specfication を行って、ZYBOt_wrapper.xsa ファイルを指定した。
アプリケーション・ソフトウエアの wl_tracking_gabor_bm.c を完成させた。ビルド済みだ。
Zybot2_37_221221.png

wl_tracking_gabor_bm.c を貼っておく。
(2022/12/21 21:55 :追記)バグがあったので修正しました。

// wl_tracking_gabor_bm.c
// 2022/12/18 : by marsee
// 2022/12/21 : bug fix. by marsee

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "sleep.h"

#include "xparameters.h"
#include "xil_io.h"
#include "xpwm.h"
#include "xmotor_monitor.h"

#define DIR_LEFT_NORMAL        1
#define DIR_LEFT_REVERSE    0
#define DIR_RIGHT_NORMAL    0
#define DIR_RIGHT_REVERSE    1

#define PIXEL_NUM_OF_BYTES    4
#define SVGA_HORIZONTAL_PIXELS  800
#define SVGA_VERTICAL_LINES     600
#define SVGA_ALL_DISP_ADDRESS   (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)

#define GABOR_DETECT_LINE        590
#define GABOR_DETECT_LINE_ADDR    (SVGA_HORIZONTAL_PIXELS * GABOR_DETECT_LINE * PIXEL_NUM_OF_BYTES)
#define GABOR_THRESHOLD            5
#define DIST_THRESHOLD            30

#define LEFT_GABOR_EDGE_OVERFLOW    0
#define RIGHT_GABOR_EDGE_OVERFLOW    (SVGA_HORIZONTAL_PIXELS/2)

//#define DEBUG
//#define MOTOR_OFF

#define FRAME_BUFFER_ADDRESS    0x10000000

void cam_i2c_init(volatile uint32_t *mt9d111_axi_iic) {
    mt9d111_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
    mt9d111_axi_iic[64] = 0x1; // enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
        // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile uint32_t *mt9d111_axi_iic, uint32_t device_addr, uint32_t write_addr, uint32_t write_data){
    mt9d111_axi_iic[66] = 0x100 | (device_addr & 0xfe);    // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    mt9d111_axi_iic[66] = write_addr;
    mt9d111_axi_iic[66] = (write_data >> 8)|0xff;            // first data
    mt9d111_axi_iic[66] = 0x200 | (write_data & 0xff);        // second data
    cam_i2x_write_sync();
}

// Gobor filter
//
void gabor_fil_on(){
    volatile uint32_t *axis_switch_0, *axis_switch_1;
    volatile uint32_t *gabor_filter_lh_0;

    axis_switch_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR;
    axis_switch_1 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR;
    gabor_filter_lh_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_GABOR_FILTER_LH_2_0_S_AXI_CONTROL_BASEADDR;

    // axis_switch_1, 1to2 ,Select M01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_1[16] = 0x80000000; // 0x40 = 0x80000000; axi_switch_0 M00_AXIS disable
    axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000; axi_switch_0 M01_AXIS disable
    axis_switch_1[18] = 0x80000000; // 0x48 = 0x80000000; axi_switch_0 M02_AXIS disable
    axis_switch_1[19] = 0x80000000; // 0x4C = 0x80000000; axi_switch_0 M03_AXIS disable
    axis_switch_1[20] = 0; // 0x50 = 0; axi_switch_4 M00_AXIS enable. gabor fitler
    axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers

    // gabor filter AXIS Start
    gabor_filter_lh_0[0] = 0x01; // Start bit set
    gabor_filter_lh_0[0] = 0x80; // Auto Restart bit set

    // axis_switch_0, 2to1, Select S01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_0[16] = 0x4; // 0x40 = 0x4; gabor fitler
    axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
}

int search_gabor_edge(unsigned int start_addr, unsigned int number, int threshold){
    volatile int *imgaddr;
    int i;

    imgaddr = (volatile int *)start_addr;

    for (i=0; i<number; i++){
        int c=imgaddr[i] & 0xff;
        //printf("%d\n",c);
        if (c >= threshold){
            break;
        }
    }
    return(i);
}

// Motor
//
void motor_settings(XPwm *motorLp, XPwm *motorRp){
    XPwm_DisableAutoRestart(motorLp);
    while(!XPwm_IsIdle(motorLp)) ;
    XPwm_Start(motorLp);
    XPwm_EnableAutoRestart(motorLp);

    XPwm_DisableAutoRestart(motorRp);
    while(!XPwm_IsIdle(motorRp)) ;
    XPwm_Start(motorRp);
    XPwm_EnableAutoRestart(motorRp);
}

void Stopped_Zybot(XPwm *motorLp, XPwm *motorRp){
    XPwm_Set_sw_late_V(motorLp, 0);
    XPwm_Set_sw_late_V(motorRp, 0);
}

void motor_initialize(XPwm *motorL, XPwm *motorR, XMotor_monitor *mmL, XMotor_monitor *mmR){
    XPwm *motorLp, *motorRp;
    XMotor_monitor *mmLp, *mmRp;

    motorLp = motorL;
    motorRp = motorR;
    mmLp = mmL;
    mmRp = mmR;

    // Initialization of motor
    if (XPwm_Initialize(motorLp, 0) != XST_SUCCESS){
        fprintf(stderr,"pwm_0 (Left) open error\n");
        exit(-1);
    }
    if (XPwm_Initialize(motorRp, 1) != XST_SUCCESS){
        fprintf(stderr,"pwm_1 (Right) open error\n");
        exit(-1);
    }

    // Initialization of motor monitor
    if (XMotor_monitor_Initialize(mmLp, 0) != XST_SUCCESS){
        fprintf(stderr,"motor_monitor_0 (Left) open error\n");
        exit(-1);
    }
    if (XMotor_monitor_Initialize(mmRp, 1) != XST_SUCCESS){
        fprintf(stderr,"motor_monitor_1 (Right) open error\n");
        exit(-1);
    }

    // The Motors is rotated in the forward direction.
    XPwm_Set_sw_late_V(motorLp, 0);
    XPwm_Set_dir_V(motorLp, 1);

    XPwm_Set_sw_late_V(motorRp, 0);
    XPwm_Set_dir_V(motorRp, 0);

    motor_settings(motorLp, motorRp);
}

int check_debug(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    return(val & 1);
}

int check_motor_on(volatile uint32_t *axi_gpio_0){
    uint32_t val = axi_gpio_0[0];
    val >>= 1;
    return(val & 1);

}

int main(){
    volatile uint32_t *dmaw4gabor_0;
    XPwm motorL, motorR;
    XMotor_monitor mmL, mmR;
    int left_wl_edge, right_wl_edge;
    volatile uint32_t *frame_buffer;
    // mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cntrler_axi_master_0
    volatile uint32_t *bmdc0_axi_lites;
    volatile uint32_t *mt9d111_axi_lites;
    volatile uint32_t *mt9d111_i2c_axi_lites;
    volatile uint32_t *axi_gpio_0;

    // axi_gpio_0 : sw0 - 0 : NORMAL, 1 : DEBUG
    //              sw1 - 0 : MOTOR OFF, 1 : MOTOR ON
    axi_gpio_0 = (volatile uint32_t *)XPAR_AXI_GPIO_0_BASEADDR;

    // Motor Initialize
    motor_initialize(&motorL, &motorR, &mmL, &mmR);

    // DMAW4Gabor Initialize
    dmaw4gabor_0 = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_DMAW4GABOR_0_S_AXI_AXILITES_BASEADDR;

    frame_buffer = (volatile uint32_t *)FRAME_BUFFER_ADDRESS;

    // DMA4Gabor frame_buffer setting
    dmaw4gabor_0[6] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Data signal of frame_buffer0
    dmaw4gabor_0[8] = (volatile uint32_t)FRAME_BUFFER_ADDRESS + (volatile uint32_t)SVGA_ALL_DISP_ADDRESS; // Data signal of frame_buffer1

    // Camera, display controller
    bmdc0_axi_lites = (volatile uint32_t *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
    mt9d111_axi_lites = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_MT9D111_INF_AXIS_0_BASEADDR;
    mt9d111_i2c_axi_lites = (volatile uint32_t *)XPAR_CAMERA_INTERFACE_AXI_IIC_0_BASEADDR;

    // IP start
    dmaw4gabor_0[0] = (volatile uint32_t)0x81; // start, auto restart
    gabor_fil_on();
    bmdc0_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 0 start
    mt9d111_axi_lites[0] = (volatile uint32_t)FRAME_BUFFER_ADDRESS; // Camera Interface start (Address is dummy)

    // CMOS Camera initialize, MT9D111
    cam_i2c_init(mt9d111_i2c_axi_lites);

    cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0xf0, 0x1);      // Changed regster map to IFP page 1
    cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0x97, 0x20);        // RGB Mode, RGB565

    mt9d111_axi_lites[1] = 0; // One_shot_mode is disabled

    // main loop
    if(check_debug(axi_gpio_0))
        printf("White line Tracking start. \n");

    while(1){
        // Gabor filter for left white line
        left_wl_edge = SVGA_HORIZONTAL_PIXELS/2 - search_gabor_edge(
            (unsigned int)frame_buffer+GABOR_DETECT_LINE_ADDR, SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);

        // Gabor filter for right white line
        right_wl_edge = search_gabor_edge(
            (unsigned int)frame_buffer+SVGA_ALL_DISP_ADDRESS+GABOR_DETECT_LINE_ADDR+(SVGA_HORIZONTAL_PIXELS/2)*PIXEL_NUM_OF_BYTES,
            SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);

        if(check_debug(axi_gpio_0))
            printf("left_wl_edge = %d, right_wl_edge = %d\n", left_wl_edge, right_wl_edge);

        if (left_wl_edge == LEFT_GABOR_EDGE_OVERFLOW){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 15);
                XPwm_Set_sw_late_V(&motorR, 45);
            }
            if(check_debug(axi_gpio_0))
                printf("Left gabor edge is overflow\n");

        } else if (right_wl_edge == RIGHT_GABOR_EDGE_OVERFLOW){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 45);
                XPwm_Set_sw_late_V(&motorR, 15);
            }
            if(check_debug(axi_gpio_0))
                printf("Right gabar edge is overflow\n");

        } else if ((right_wl_edge - left_wl_edge) > DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 35);
                XPwm_Set_sw_late_V(&motorR, 25);
            }
            if(check_debug(axi_gpio_0))
                printf("Right turn\n");

        } else if ((right_wl_edge - left_wl_edge) < -DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 25);
                XPwm_Set_sw_late_V(&motorR, 35);
            }
            if(check_debug(axi_gpio_0))
                printf("Left turn\n");

        } else if (abs(right_wl_edge - left_wl_edge) <= DIST_THRESHOLD){
            if(check_motor_on(axi_gpio_0)){
                XPwm_Set_sw_late_V(&motorL, 30);
                XPwm_Set_sw_late_V(&motorR, 30);
            }
            if(check_debug(axi_gpio_0))
                printf("Go straight\n");
        }
    }
}


  1. 2022年12月21日 04:30 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行するためのコースを用意する

Zybot 用のバッテリーも来たので、テストしようとした。
コースは一部壊れているけど、カーペットの下に用意されている。ただ、テープが剥がれているので、作り直す必要がある。物をどかしてカーペットを取ってテストする必要があるため、家族が居る時はできない。近くの室内に常設コースが欲しい。パソコンとディスプレイも周囲に必要となるんだよね。。。
Zybot2_36_221220.jpg

Zybot で Gabor filter を使うためのZYBO_0_5 プロジェクト5(走行テスト)”の wl_tracing_damw.c はカメラの初期化やカメラ用 DMA の初期化部分が無かった。wl_tracing_damw.c は、それらを初期化してから起動していたようだ。
という訳で、一旦ベアメタルに直した wl_tracing_damw.c にカメラや DMA の初期化ルーチンを追加する。
ベアメタルでなく、ikwzm さんの Debian でやった方が良いかな?
  1. 2022年12月20日 06:37 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する6(Vitis 2022.2 でアプリケーション・ソフトを作成)

Zybot でガボール・フィルタを使用して白線間走行する5(Gabor_Filter_lh_2 IP を ZYBOt_222 プロジェクトで使用する)”の続き。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、Vitis HLS 2022.2 で作成した Gabor_Filter_lh_2 プロジェクトを Vivado 2022.2 の ZYBOt_222 プロジェクトのブロック・デザインに入れて、論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。今回は、Vivado 2022.2 でハードウエアをエクスポートして、Vitis でプラットフォームとアプリケーション・ソフトウエアを作成しようとするが、まだ途中だ。

Vivado 2022.2 でハードウエアをエクスポートした。
ZYBOt_wrapper.xsa が生成された。
Zybot2_28_221219.png

Vivado から Vitis 2022.2 を起動して、プラットフォームと wl_tracking_gabor_bm アプリケーション・プロジェクトを作成した。
Zybot2_29_221219.png

アプリケーション・ソフトウエアとして、wl_tracking_gabor_bm.c を作成したが、まだ変更の途中だ。
Zybotのカメラによる白線追従走行”の wl_tracking.cpp を Linux アプリケーションからベアメタル・アプリケーションにコードを変更中だ。
Zybot2_30_221219.png

なお、”Zybotのカメラによる白線追従走行”のときに使用していた Zybot はバッテリーがダメになってしまったようので、バッテリーだけを購入したので、今日届くはず。。。
Zybot2_31_221219.jpg
  1. 2022年12月19日 05:25 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する5(Gabor_Filter_lh_2 IP を ZYBOt_222 プロジェクトで使用する)

Zybot でガボール・フィルタを使用して白線間走行する4(Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクト2)”の続き。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、Vitis HLS 2022.2 で Gabor_Filter_lh_2 プロジェクトの C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL、Implementation を行った。今回は、Vitis HLS 2022.2 で作成した Gabor_Filter_lh_2 プロジェクトを Vivado 2022.2 の ZYBOt_222 プロジェクトのブロック・デザインに入れて、論理合成、インプリメンテーション、ビットストリームの生成を行って、成功した。

Vivado 2022.2 の ZYBOt_222 プロジェクトのディレクトリに Gabor_Filter_lh_2 ディレクトリを作成して、その中に、Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクトの solution1 / impl ディレクトリの export.zip を展開して入れた。
Zybot2_22_221216.png

IP Catalog に Gabor_Filter_lh_2 IP を登録した。
Zybot2_23_221216.png

Gabor_Filter_lh_2 IP を Add IP することで、ZYBOt ブロック・デザインの最上位層も変更になったので、貼っておく。
Zybot2_24_221217.png
Zybot2_25_221217.png

Gabor_Filter_lh_2 IP を Add IP した camera_interface 階層モジュールを示す。
Zybot2_26_221217.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。今度は成功した。
Zybot2_27_221217.png
  1. 2022年12月17日 04:20 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する4(Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクト2)

Zybot でガボール・フィルタを使用して白線間走行する3(Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクト)”の続き。

(2022/12/16:修正) RorL を外部出力ピンに変更しましたが、この記事は AXI4-Lite インターフェースになっています。リソース使用量が多少減っている程度で、合成後のレイテンシは変更なしでした。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、ガボール・フィルタ IP でタイミング・エラーが発生したので、ガボール・フィルタ IP を Vitis HLS 2022.2 で作り直そうということで、ソースコードを貼って、Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクトを示した。今回は、Vitis HLS 2022.2 で C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL、Implementation を行った。

C シミュレーションを行った。結果を示す。
Zybot2_12_221215.png

Gabor_Filter_lh_2/solution1/csim/build ディレクトリにガボール・フィルタが掛かったファイルが出力された。
Zybot2_13_221215.png

元画像の road_1.bmp ファイルを示す。
Zybot2_14_221215.jpg

左白線用パラメータのガボール・フィルタ結果を示す。
Zybot2_15_221215.jpg

右白線のガボール・フィルタ結果を示す。
Zybot2_16_221215.jpg

C コードの合成を行った。結果を示す。
Zybot2_17_221215.png
Zybot2_18_221215.png

Latency は 960024 クロックだった。800 x 600 ピクセルの画像を 2 回ガボール・フィルタを掛けているので、ほぼ 1 クロック/ピクセルになっている。性能が良い。

C/RTL 協調シミュレーションを行った。結果を示す。
Zybot2_19_221215.png

Latency は 960026 クロックだった。
C/RTL 協調シミュレーションの全体波形を示す。
outs_TVALID と ins_TREADY が 1 のままだった。性能が良い。
Zybot2_20_221215.png

Export RTL を行った。Gabor_Filter_lh_2/solution1/impl に Gagor_Filter_lh_2 IP を圧縮した export.zip が生成された。

Implementation を行った。結果を示す。
Zybot2_21_221216.png

CP achieved post-Implementation は 9.454 ns で少し危なそうだが、これ以上パイプラインに切れないので、仕方ない。
  1. 2022年12月16日 03:56 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する3(Vitis HLS 2022.2 の Gabor_Filter_lh_2 プロジェクト)

Zybot でガボール・フィルタを使用して白線間走行する2(Vivado 2022.2 の Zybot_222 プロジェクト)”の続き。

(2022/12/16:修正) RorL を外部出力ピンに変更した。

Zybot でガボール・フィルタを使用して白線間を走行させたいと思っているということで、前回は、”Zybot による障害物回避”のハードウエアを Vivado 2022.2 に変換して、論理合成、インプリメンテーション、ビットストリームの生成を行ったところ、タイミング・エラーが発生した。今回は、ガボール・フィルタ IP でタイミング・エラーが発生したので、ガボール・フィルタ IP を Vitis HLS 2022.2 で作り直そうと思う。今回は、ソースコードを貼った。

まずは、BMP ファイル用のヘッダ・ファイルの bmp_header.h が必要だ。bmp_header.h は、”kv260_median_platform のメディアン・フィルタを KV260 の Petalinux から動作させる27”に貼ってある。

次に、Gabor_filter_lh_2.h を貼っておく。

// Gabor_filter_lh_2.h
// 2016/07/24
// 2016/07/25 : 右白線検出用のGabor Filterの重みを追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
//

#ifndef __Gabor_filter_lh_H__
#define __Gabor_filter_lh_H__

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600

//#define HORIZONTAL_PIXEL_WIDTH    640 // for Simulation
//#define VERTICAL_PIXEL_WIDTH    480

//#define HORIZONTAL_PIXEL_WIDTH    64
//#define VERTICAL_PIXEL_WIDTH    48

#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define ARRAY_SIZE  9

#define RIGHT_WEIGHT    1
#define LEFT_WEIGHT     0
#define L_R_WEIGHT      2

const int gabor_weight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用
    {
        {0,-3,-10,-16,-7,7,10,5,1},
        {-3,-15,-27,-11,32,50,29,5,-2},
        {-11,-24,-5,73,135,95,16,-17,-10},
        {-11,4,85,187,160,14,-72,-52,-14},
        {4,51,135,137,-18,-159,-136,-45,-2},
        {16,50,59,-39,-179,-185,-73,3,13},
        {10,12,-25,-104,-131,-60,15,27,11},
        {1,-7,-31,-48,-24,18,29,14,3},
        {-1,-5,-9,-4,10,16,10,2,-1}
    },
    {
        {1,5,7,1,-12,-17,-10,-3,0},
        {1,11,33,45,21,-16,-27,-15,-4},
        {-8,-5,35,107,131,69,-2,-21,-11},
        {-17,-47,-51,40,169,187,93,13,-7},
        {-8,-54,-134,-147,-18,123,130,58,11},
        {9,-6,-82,-185,-187,-65,36,44,17},
        {11,24,12,-55,-125,-112,-43,1,7},
        {3,14,30,23,-13,-41,-33,-12,-1},
        {0,2,9,17,14,1,-6,-5,-2}
    }
};
const float gabor_fweight[2][ARRAY_SIZE][ARRAY_SIZE] = { // 左白線検出用+右白線検出用(float)
    {
        {0.001282,-0.009914,-0.04062,-0.060586,-0.027574,0.026072,0.038427,0.018191,0.003056},
        {-0.012155,-0.057448,-0.104645,-0.042953,0.123263,0.197238,0.114451,0.020448,-0.007239},
        {-0.042252,-0.093065,-0.018911,0.285374,0.525746,0.372687,0.060734,-0.064748,-0.040465},
        {-0.042261,0.015673,0.332798,0.728763,0.625046,0.053591,-0.283076,-0.203293,-0.05608},
        {0.017342,0.198305,0.52554,0.535526,-0.069756,-0.622839,-0.531089,-0.177366,-0.006367},
        {0.060866,0.19708,0.231032,-0.154219,-0.699885,-0.721808,-0.286707,0.013004,0.049249},
        {0.038379,0.04877,-0.098477,-0.404993,-0.510165,-0.233566,0.057894,0.104366,0.041887},
        {0.0047,-0.0278,-0.121277,-0.187262,-0.093276,0.070512,0.113857,0.055799,0.009976},
        {-0.003798,-0.01885,-0.035607,-0.01709,0.037692,0.064268,0.038606,0.007536,-0.002133}
    },
    {
        {0.005562,0.018882,0.028293,0.004499,-0.044995,-0.064838,-0.039469,-0.009822,0.000815},
        {0.002294,0.04108,0.127023,0.175094,0.083025,-0.063755,-0.106402,-0.057798,-0.01406},
        {-0.031269,-0.021096,0.135641,0.417286,0.512467,0.269946,-0.008354,-0.082091,-0.041357},
        {-0.066348,-0.184919,-0.197802,0.15614,0.65976,0.728616,0.361674,0.052074,-0.027152},
        {-0.031146,-0.211178,-0.523777,-0.573856,-0.069756,0.480311,0.506451,0.225223,0.041031},
        {0.035552,-0.023892,-0.320104,-0.723563,-0.728735,-0.253689,0.1391,0.170625,0.067723},
        {0.04216,0.094939,0.047511,-0.216623,-0.488075,-0.437898,-0.168739,0.003336,0.027009},
        {0.012112,0.056596,0.115239,0.090332,-0.05076,-0.158403,-0.127847,-0.046375,-0.004918},
        {-0.00168,0.007437,0.036985,0.067021,0.053689,0.004977,-0.02365,-0.018248,-0.005928}
    }
};

#endif


ソースコードの Gabor_filter_lh_2.cpp を貼っておく。

// Gabor_fiter_lh_2.cpp
// 2016/07/23 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2016/07/27 : 右白線検出用配列と左白線検出用配列を統合
// 2016/08/29 : 1回目左白線検出、2回目右白線検出のモードを追加
// 2022/12/14 : Vitis HLS用に書き直した
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "Gabor_filter_lh_2.h"

int conv_rgb2y(int rgb);

int Gabor_filter_lh_2(hls::stream<ap_axis<32,1,1,1> >& ins,
        hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL){
#pragma HLS INTERFACE mode=ap_none port=RorL
#pragma HLS INTERFACE mode=axis register_mode=both port=ins register
#pragma HLS INTERFACE mode=axis register_mode=both port=outs register
#pragma HLS INTERFACE mode=s_axilite port=return

    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    ap_int<32> line_buf[ARRAY_SIZE-1][1920]; // Up to HD resolution
#pragma HLS array_partition variable=line_buf block factor=2 dim=1

    ap_int<32> pix_mat[ARRAY_SIZE][ARRAY_SIZE];
    int gray_pix, val, i, j, x, y, k;

    LOOP_WAIT_USER: do {
#pragma HLS LOOP_TRIPCOUNT avg=1 max=1 min=1
    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    LOOP_LR: for (k=0; k<2; k++){
        LOOP_Y: for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
            LOOP_X: for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS PIPELINE II=1
                if (!(k==0 && x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                LOOP_PIX_MAT_K: for(int k=0; k<ARRAY_SIZE; k++){
                    LOOP_PIX_MAT_M: for(int m=0; m<ARRAY_SIZE-1; m++){
                        pix_mat[k][m] = pix_mat[k][m+1];
                    }
                }
                for (i=0; i<ARRAY_SIZE-1; i++){
                    pix_mat[i][ARRAY_SIZE-1] = line_buf[i][x];
                }
                ap_int<32> y_val = conv_rgb2y(pix.data);
                pix_mat[ARRAY_SIZE-1][ARRAY_SIZE-1] = y_val;

                for (i=0; i<ARRAY_SIZE-2; i++){    // 行の入れ替え
                    line_buf[i][x] = line_buf[i+1][x];
                }
                line_buf[ARRAY_SIZE-2][x] = y_val;

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = L_R_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE; j++){
                    for (i=0; i<ARRAY_SIZE; i++){
                        val += gabor_weight[ano][j][i] * pix_mat[j][i];
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                gabor.data = (val<<16)+(val<<8)+val;
                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1))
                    gabor.data = 0;

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (HORIZONTAL_PIXEL_WIDTH-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


テストベンチの Gabor_filter_lh_2_tb.cpp を貼っておく。

// Gabor_filter_lh_2_tb.cpp
// 2016/07/24 by marsee
// 2016/07/25 : 右白線検出用のGabor Filterを追加して、右左の白線を指定するRorL 引数を追加
// 2022/12/14 : Vitis HLS用に書き直した
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <ap_axi_sdata.h>

#include "Gabor_filter_lh_2.h"
#include "bmp_header.h"

int Gabor_filter_lh_2(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL);

int conv_rgb2y_soft(int rgb);
int Gabor_filter_lh_2_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL);

#define CLOCK_PERIOD 10
#define RIGHT_OR_LEFT   L_R_WEIGHT
#define BMP_FILE_NAME   "road_1.bmp"

int main()
{
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > ins;
    hls::stream<ap_axis<32,1,1,1> > ins_soft;
    hls::stream<ap_axis<32,1,1,1> > outs;
    hls::stream<ap_axis<32,1,1,1> > outs_soft;
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> vals;
    ap_axis<32,1,1,1> vals_soft;

    int m_seq = 1; // M系列の値
    int i, k;
    int xor_shift;

    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw, *fbmpwf;
    int *rd_bmp, *hw_gabor, *sw_gabor;
    int blue, green, red;
    ap_uint<2> r_l;
    char fhname[100];
    char fsname[100];

    if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // test.bmp をオープン
        fprintf(stderr, "Can't open test.bmp by binary read mode\n");
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    printf("bmpihr.biWidth = %d, bmpihr.biHeight = %d\n",(int)bmpihr.biWidth, (int)bmpihr.biHeight);
    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }
    if ((sw_gabor =(int *)malloc(2 * sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_gabor memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);

    // ins に入力データを用意する
    for(int i=0; i<5; i++){    // dummy data
        pix.user = 0;
        pix.data = i;
        ins << pix;
    }

    // 2画面分を入力する
    for(int k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];

                if (j==0 && i==0)    // 最初のデータの時に TUSER を 1 にする
                    pix.user = 1;
                else
                    pix.user = 0;

                if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
                    pix.last = 1;
                else
                    pix.last = 0;

                ins << pix;
                ins_soft << pix;
            }
        }
    }

    r_l = (ap_uint<2>)RIGHT_OR_LEFT;
    Gabor_filter_lh_2(ins, outs, r_l);
    Gabor_filter_lh_2_soft(ins_soft, outs_soft, r_l);

    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    cout << endl;
    cout << "outs" << endl;
    for(k=0; k<2; k++){
        for(int j=0; j < bmpihr.biHeight; j++){
            for(i=0; i < bmpihr.biWidth; i++){
                outs >> vals;
                outs_soft >> vals_soft;
                ap_int<32> val = vals.data;
                ap_int<32> val_soft = vals_soft.data;

                hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val;
                sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+(j*bmpihr.biWidth)+i] = (int)val_soft;

                //printf("k=%d, j=%d, i=%d\n",k,j,i);
                if ((double)pow((double)(val&0xff)-(val_soft&0xff),(double)2) > 4){ // 2乗誤差が4よりも大きい
                    printf("ERROR HW and SW results mismatch i = %ld, j = %ld, HW = %08x, SW = %08x\n", i, j, (int)val, (int)val_soft);
                    //return(1);
                }
                //if (vals.last)
                    //cout << "AXI-Stream is end" << endl;
            }
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    // ハードウェアのラプラシアンフィルタの結果を temp_gabor0.bmp, temp_gabor1.bmp へ出力する
    for(k=0; k<2; k++){
        if(k == 0){
            if ((fbmpw=fopen("temp_gabor0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpw=fopen("temp_gabor1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (hw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpw);
                fputc(green, fbmpw);
                fputc(red, fbmpw);
            }
        }
        fclose(fbmpw);
    }

    // ソフトウェアのラプラシアンフィルタの結果を temp_gabor_float0.bmp, temp_gabor_float1.bmp へ出力する
    for(k=0; k<2; k++){
        if (k == 0){
            if ((fbmpwf=fopen("temp_gabor_float0.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float0.bmp by binary write mode\n");
                exit(1);
            }
        } else {
            if ((fbmpwf=fopen("temp_gabor_float1.bmp", "wb")) == NULL){
                fprintf(stderr, "Can't open temp_gabor_float1.bmp by binary write mode\n");
                exit(1);
            }
        }

        // BMPファイルヘッダの書き込み
        fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpwf);
        fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpwf);
        fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpwf);
        // RGB データの書き込み、逆順にする
        for (int y=0; y<bmpihr.biHeight; y++){
            for (int x=0; x<bmpihr.biWidth; x++){
                blue = sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
                green = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
                red = (sw_gabor[bmpihr.biWidth*bmpihr.biHeight*k+((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

                fputc(blue, fbmpwf);
                fputc(green, fbmpwf);
                fputc(red, fbmpwf);
            }
        }
        fclose(fbmpwf);
    }

    free(rd_bmp);
    free(hw_gabor);

    return 0;
}

int Gabor_filter_lh_2_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs, ap_uint<2> & RorL){
    ap_axis<32,1,1,1> pix;
    ap_axis<32,1,1,1> gabor;

    ap_int<32> line_buf[ARRAY_SIZE-1][1920]; // Up to HD resolution
    ap_int<32> pix_mat[ARRAY_SIZE][ARRAY_SIZE];
    int gray_pix, val, i, j, x, y, k;

    do {
    // user が 1になった時にフレームがスタートする
        ins >> pix;
    } while(pix.user == 0);

    for (k=0; k<2; k++){
        for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
            for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
                if (!(k==0 && x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力

                for(int k=0; k<ARRAY_SIZE; k++){
                    for(int m=0; m<ARRAY_SIZE-1; m++){
                        pix_mat[k][m] = pix_mat[k][m+1];
                    }
                }
                for (i=0; i<ARRAY_SIZE-1; i++){
                    pix_mat[i][ARRAY_SIZE-1] = line_buf[i][x];
                }
                ap_int<32> y_val = conv_rgb2y_soft(pix.data);
                pix_mat[ARRAY_SIZE-1][ARRAY_SIZE-1] = y_val;

                for (i=0; i<ARRAY_SIZE-2; i++){    // 行の入れ替え
                    line_buf[i][x] = line_buf[i+1][x];
                }
                line_buf[ARRAY_SIZE-2][x] = y_val;

                // 使用する配列を決定する
                int ano;
                switch (RorL){
                case LEFT_WEIGHT :
                    ano = LEFT_WEIGHT;
                    break;
                case RIGHT_WEIGHT :
                    ano = RIGHT_WEIGHT;
                    break;
                case L_R_WEIGHT :
                    if (k == 0)
                        ano = LEFT_WEIGHT;
                    else
                        ano = RIGHT_WEIGHT;
                    break;
                default :
                    ano = L_R_WEIGHT;
                    break;
                }

                // Gabor filter の演算
                for (j=0, val=0; j<ARRAY_SIZE; j++){
                    for (i=0; i<ARRAY_SIZE; i++){
                        val += gabor_weight[ano][j][i] * pix_mat[j][i];
                    }
                }
                val = val/256; // 256倍してあるので、1/256して戻す
                if (val<0)
                    //val = -val; // 絶対値
                    val = 0; // マイナスの値を0に丸める
                else if (val>255)
                    val = 255;

                // Gabor filter・データの書き込み
                gabor.data = (val<<16)+(val<<8)+val;
                // 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-1列は無効データなので0とする
                if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1))
                    gabor.data = 0;

                if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                    gabor.user = 1;
                else
                    gabor.user = 0;

                if (x == (HORIZONTAL_PIXEL_WIDTH-1))    // 行の最後で TLAST をアサートする
                    gabor.last = 1;
                else
                    gabor.last = 0;

                outs << gabor;    // AXI4-Stream へ出力
             }
         }
    }
     return(0);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}


Vitis HLS 2022.2 の Gabor_filter_lh_2 プロジェクトを示す。
Zybot2_11_221215.png
  1. 2022年12月15日 04:59 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する2(Vivado 2022.2 の Zybot_222 プロジェクト)

Zybot でガボール・フィルタを使用して白線間走行する1”の続き。

今回は、”Zybot による障害物回避”のハードウエアを Vivado 2022.2 に変換して、論理合成、インプリメンテーション、ビットストリームの生成を行ったところ、タイミング・エラーが発生した。

Zybot による障害物回避”のハードウエアを Vivado 2022.2 に変換した ZYBOt_222 プロジェクトを示す。
Zybot2_1_221214.png

ZYBOt ブロック・デザインを示す。
Zybot2_2_221214.png
Zybot2_3_221214.png

Address Editor を示す。
Zybot2_4_221214.png

camera_interface 階層モジュールを示す。
Zybot2_5_221214.png

ここにガボール・フィルタが実装されている。

PmodHB5_inf_left 階層モジュールを示す。これは、左車輪の Hブリッジ駆動用 PWM IP などがある。
Zybot2_6_221214.png

PmodHB5_inf_right 階層モジュールを示す。これは、右車輪の Hブリッジ駆動用 PWM IP などがある。
Zybot2_7_221214.png

usonic_sensor_inf 階層モジュールを示す。これは超音波距離測定器用モジュールとなっている。
Zybot2_8_221214.png

論理合成、インプリメンテーション、ビットストリームの生成を行ったところ、タイミング・エラーが発生した。
Zybot2_9_221214.png

タイミング・エラーは Intra-Clock Paths の clk_fpga0 で発生していた。
ガボール・フィルタ IP 内のタイミングのようだ。。。
Zybot2_10_221214.png

ガボール・フィルタ IP をもう一度高位合成しなおそう。。。
  1. 2022年12月14日 04:37 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Zybot でガボール・フィルタを使用して白線間走行する1

以前使用していた Zybot が何処にあるか分からなくなってしまったが、探し出してみよう。
Zybot には旧 ZYBO が搭載されていたが、それを ZYBO Z7-20 にしてガボール・フィルタで白線を検出して白線間を走行させたい。
ガボール・フィルタで白線間を走行させたら、白線間の画像データを取得して、CNN (畳み込みニューラルネットワーク)をその画像データで学習させたい。
ガボール・フィルタを CNN に切り替えて、今度は CNN の出力で白線間を走行させたいと思っている。
ZYBOtを家のコースで走らせてみた”で学習データを作るのが難しいのはよく分かったので、ガボール・フィルタでうまく走行できれば、それを利用して学習データを作成しようという作戦だ。

本当は ZYBO Z7-20 じゃなくて、KR260 でやってみたいがロボットカーが無いので、たぶん探せばあると思う ZYBOt でやってみよう。(でも早く KR260 もやってみたい)
カメラ回路入りの ZYBO Z7-20 の Vitis アクセラレーション・プラットフォームを作成して、DPU で実装できたら良いのだが、ちょっと無理かな?

とりあえずは ZYBO 用の CNN 白線間走行プロジェクトを最新の Vivado 2022.2 に変換してみよう。

コースは TatamiRacer みたいなコンパクトなコースを室内に用意しよう。とりあえずはオーバル・コースで良いのではないだろうか?
  1. 2022年12月13日 05:30 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる4

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる3”の続き。

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる3”では、7 の数字の認識だけやったので、時分で書いた手書き数字はどのくらい認識できるか?試してみたところ、8 と 9 の推論が間違っていた。

用意した手書き数字を示す。使用するのは黒地に白文字の n0.bmp 〜 n9.bmp までだ。
Custom_OP_Workflow_53_221211.png

手書き数字を KV260 の Petalinux 2022.1 の ~/tensorflow2_example/handwriting ディレクトリにアップロードした。

カスタム OP デモを実行ための環境を設定する。
cd ~/kv260_median/dpu
sudo mkdir -p /run/media/mmcblk0p1/
sudo cp dpu.xclbin /run/media/mmcblk0p1/
sudo xmutil unloadapp
sudo xmutil loadapp dpuprj
cd ~/tensorflow2_example/deployment/cpp


カスタム OP デモを実行した。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n0.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n1.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n2.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n3.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n4.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n5.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n6.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n7.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n8.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n9.bmp

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n0.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n0.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:30:44.679307  1273 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n0.bmp result:
    score[0]   =  0.992188    
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0           
    score[4]   =  0           
    score[5]   =  0           
    score[6]   =  0.0390625   
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n1.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n1.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:30:54.338976  1282 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n1.bmp result:
    score[0]   =  0           
    score[1]   =  0.992188    
    score[2]   =  0.0859375   
    score[3]   =  0           
    score[4]   =  0           
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0.210938    
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n2.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n2.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:30:59.285208  1287 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n2.bmp result:
    score[0]   =  0.164062    
    score[1]   =  0           
    score[2]   =  0.210938    
    score[3]   =  0           
    score[4]   =  0           
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0.25        
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n3.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n3.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:15.731254  1300 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n3.bmp result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0.992188    
    score[4]   =  0           
    score[5]   =  0.164062    
    score[6]   =  0           
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n4.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n4.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:20.559351  1305 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n4.bmp result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0.0390625   
    score[3]   =  0           
    score[4]   =  0.789062    
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0.5         
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n5.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n5.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:26.883575  1310 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n5.bmp result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0.125       
    score[4]   =  0           
    score[5]   =  0.992188    
    score[6]   =  0           
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n6.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n6.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:31.589458  1315 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n6.bmp result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0           
    score[4]   =  0.414062    
    score[5]   =  0.125       
    score[6]   =  0.585938    
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n7.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n7.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:39.147933  1324 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n7.bmp result:
    score[0]   =  0           
    score[1]   =  0.414062    
    score[2]   =  0           
    score[3]   =  0           
    score[4]   =  0.289062    
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0.625       
    score[8]   =  0           
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n8.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n8.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:31:54.020833  1337 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n8.bmp result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0.460938    
    score[4]   =  0.5         
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0           
    score[8]   =  0.335938    
    score[9]   =  0           
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/handwriting/n9.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/handwriting/n9.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1211 04:32:02.205699  1342 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/handwriting/n9.bmp result:
    score[0]   =  0           
    score[1]   =  0.210938    
    score[2]   =  0           
    score[3]   =  0.375       
    score[4]   =  0           
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0           
    score[8]   =  0           
    score[9]   =  0           


手書き数字、8 と 9 の推論が外れている。
精度は 8 / 10 = 0.8 で 80 % の精度ということができる。
  1. 2022年12月12日 04:00 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する5

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する4”の続き。

自作の白線間走行用 CNN を Vitis-AI の Custom OP WorkFlow で実行する1”のソースコードだが、”白線間走行用CNNをKerasで学習する”を見ると、配列の次元の位置を変えるには transpose じゃなくて reshape のようだったので、ソースコードを変更した。

変更した train_eval_line.py を貼っておく。

# Copyright 2019 Xilinx Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# train_eval_line.py
# 2022/12/05 : modified by marsee
# 2022/12/08 : modified by marsee

import os, sys
import numpy as np
import tensorflow as tf
import argparse

print(tf.__version__)

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

from curve_dataset import load_mnist
from tensorflow.keras import utils as np_utils

parser = argparse.ArgumentParser(description='tensorflow 2 custom op example.')
parser.add_argument('--eval_only', type=bool, default=False, help='if only evaluate model')
parser.add_argument('--quant', type=bool, default=False, help='if evluate quantized model')

args = parser.parse_args()


class Mylayer(tf.keras.layers.Layer):
  def __init__(self, name="custom_layer", **kwargs):
    super().__init__(name=name, **kwargs)
    self.prelu = tf.keras.layers.PReLU()

  def call(self, inputs, training=None, mask=None):
    x = self.prelu(inputs)
    return x

custom_objects = {"Mylayer": Mylayer}

def build_model():
  inputs = tf.keras.Input((10, 56, 1))
  x = tf.keras.layers.Conv2D(2, (5, 5), activation='relu')(inputs)

  x = tf.keras.layers.MaxPooling2D((2, 2), (2, 2))(x)

  my_model = Mylayer()
  x = my_model(x)

  x = tf.keras.layers.Flatten()(x)
  x = tf.keras.layers.Dense(100, activation='relu')(x)
  x = tf.keras.layers.Dense(3, activation='softmax')(x)

  model = tf.keras.Model(inputs=inputs, outputs=x)
  return model

def main():
  #################################
  ###### build dataset
  #################################
  (x_train, y_train), (x_test, y_test) = load_mnist(normalize=False, flatten=False)
  trainzip = list(zip(y_train, x_train))
  np.random.shuffle(trainzip)
  y_train, x_train = zip(*trainzip)
  x_train = np.asarray(x_train)
  y_train = np.asarray(y_train)

  testzip = list(zip(y_test, x_test))
  np.random.shuffle(testzip)
  y_test, x_test = zip(*testzip)
  x_test = np.asarray(x_test)
  y_test = np.asarray(y_test)

  x_train = x_train.reshape(x_train.shape[0], 10, 56, 1)
  x_test = x_test.reshape(x_test.shape[0], 10, 56, 1)
  
  x_train = x_train.astype('float32')
  x_test = x_test.astype('float32')
  x_train /= 255
  x_test /= 255

  y_train = y_train.astype('int32')
  y_test = y_test.astype('int32')
  y_train = np_utils.to_categorical(y_train, 3)
  y_test =  np_utils.to_categorical(y_test, 3)

  #################################
  ##### evaluate model
  #################################
  if args.eval_only:
    if args.quant:
      from tensorflow_model_optimization.quantization.keras import vitis_quantize
      # quantized_model = tf.keras.models.load_model("./quantized/quantized.h5",
      #         custom_objects=custom_objects)
      with vitis_quantize.quantize_scope():
        quantized_model = tf.keras.models.load_model("./quantized/quantized_curve_line.h5",
                custom_objects=custom_objects)
        quantized_model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
        eval_results = quantized_model.evaluate(x_test, y_test)
        print("\n***************** Summary *****************")
        print("Quantized model accuracy: ", eval_results[1])
      return
    loaded_model = tf.keras.models.load_model("./keras_curve_cnn2_line.h5",
            custom_objects=custom_objects)
    eval_results = loaded_model.evaluate(x_test, y_test)
    print("\n***************** Summary *****************")
    print("Float model accuracy: ", eval_results[1])
    return
  #################################
  ##### build model
  #################################
  model = build_model()
  model.summary()
  #################################
  ##### compile train
  #################################
  model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
  model.fit(x_train, y_train, epochs=7, shuffle=True)
  eval_results = model.evaluate(x_test, y_test)
  print("\n***************** Summary *****************")
  print("Trained float model accuracy: ", eval_results[1])
  save_path = "./keras_curve_cnn2_line.h5"
  print("Trained float model is saved in ", save_path)
  model.save(save_path)

if __name__ == '__main__':
  main()


quantize_curve_line.py を貼っておく。

# Copyright 2019 Xilinx Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# quantize_curve_line.py
# 2022/12/05 : modified by marsee

import os, sys
import numpy as np
import tensorflow as tf

from curve_dataset import load_mnist
from train_eval_line import custom_objects

print(tf.__version__)
os.environ["CUDA_VISIBLE_DEVICES"] = "0"


def main():
#################################
###### build dataset
#################################
(x_train, y_train), (x_test, y_test) = load_mnist(normalize=False, flatten=False)

testzip = list(zip(y_test, x_test))
np.random.shuffle(testzip)
y_test, x_test = zip(*testzip)
x_test = np.asarray(x_test)
y_test = np.asarray(y_test)
x_test = x_test.reshape(x_test.shape[0], 10, 56, 1)
x_test = x_test.astype('float32')
x_test /= 255

#################################
##### quantize model
#################################
loaded_model = tf.keras.models.load_model("./keras_curve_cnn2_line.h5",
custom_objects=custom_objects)
loaded_model.summary()
from tensorflow_model_optimization.quantization.keras import vitis_quantize
# do quantization
calib_dataset = x_test
quant_model = vitis_quantize.VitisQuantizer(loaded_model, custom_objects=custom_objects).quantize_model(
calib_dataset=calib_dataset,
add_shape_info=True)
# quant_model.summary()
q_save_path = os.path.join('./quantized', 'quantized_curve_line.h5')
quant_model.save(q_save_path)
print("\n***************** Summary *****************")
print("Quantized model is saved in ", q_save_path)

if __name__ == '__main__':
main()


Vitis-AI の Docker を起動して、学習を行った。
./docker_run.sh xilinx/vitis-ai-cpu:2.5
cd tf2_custom_op_demo
conda activate vitis-ai-tensorflow2
python tran_eval_line.py

Custom_OP_Workflow_50_221211.png

量子化を行った。
python quantize_curve_line.py
Custom_OP_Workflow_51_221211.png

コンパイルして、XMODEL を作成した。
vai_c_tensorflow2 -m ./quantized/quantized_curve_line.h5 -a ../kv260_myarch.json -o ./ -n tf2_curve_line
Custom_OP_Workflow_52_221211.png

XMODEL を FileZilla で KV260 の Petalinux 2022.1 にアップロードした。

まずは、kv260 の Petalinux 2022.1 の環境を設定した。
cd ~/kv260_median/dpu
sudo mkdir -p /run/media/mmcblk0p1/
sudo cp dpu.xclbin /run/media/mmcblk0p1/
sudo xmutil unloadapp
sudo xmutil loadapp dpuprj
cd ~/tensorflow2_example/deployment/cpp


今まで、JPG 画像で推論してきたが、元が BMP 画像での学習なので、BMP 画像で推論を行った。

最初は直進のパターンを推論した。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_00.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_01.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_02.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_03.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_04.bmp

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_00.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect0_00.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:27:18.511101  1328 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect0_00.bmp result:
    score[0]   =  0.957431    
    score[1]   =  0.0289119   
    score[2]   =  0.013657    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_01.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect0_01.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:27:29.567533  1341 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect0_01.bmp result:
    score[0]   =  0.546549    
    score[1]   =  0.331499    
    score[2]   =  0.121952    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_02.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect0_02.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:27:34.319573  1346 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect0_02.bmp result:
    score[0]   =  0.554841    
    score[1]   =  0.432111    
    score[2]   =  0.0130486   
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_03.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect0_03.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:27:38.321185  1347 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect0_03.bmp result:
    score[0]   =  0.261528    
    score[1]   =  0.710907    
    score[2]   =  0.0275649   
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect0_04.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect0_04.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:27:56.568765  1364 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect0_04.bmp result:
    score[0]   =  0.74834     
    score[1]   =  0.214403    
    score[2]   =  0.0372576   


5 回推論して、1 回しか合っていないということは。。。

左旋回のパターンを推論した。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_00.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_01.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_02.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_03.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_04.bmp

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_00.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_00.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:44:29.216714  2167 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_00.bmp result:
    score[0]   =  0.145139    
    score[1]   =  0.835218    
    score[2]   =  0.0196425   
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_01.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_01.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:44:43.451567  2181 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_01.bmp result:
    score[0]   =  0.542674    
    score[1]   =  0.422635    
    score[2]   =  0.034692    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_02.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_02.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:44:52.339522  2190 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_02.bmp result:
    score[0]   =  0.960332    
    score[1]   =  0.0289995   
    score[2]   =  0.0106683   
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_03.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_03.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:44:56.608392  2195 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_03.bmp result:
    score[0]   =  0.999186    
    score[1]   =  0.000261046 
    score[2]   =  0.000552634 
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_04.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_04.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:45:00.314903  2196 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_04.bmp result:
    score[0]   =  0.89917     
    score[1]   =  0.00605856  
    score[2]   =  0.0947718   


左旋回は 5 回推論して 4 回当たっている。

右旋回のパターンを推論した。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_00.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_01.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_02.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_03.bmp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_04.bmp

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_00.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_00.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:48:50.522089  2382 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_00.bmp result:
    score[0]   =  0.00135824  
    score[1]   =  0.09522     
    score[2]   =  0.903422    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_01.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_01.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:48:56.709283  2391 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_01.bmp result:
    score[0]   =  5.81789e-05 
    score[1]   =  0.222687    
    score[2]   =  0.777255    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_02.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_02.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:49:01.729414  2396 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_02.bmp result:
    score[0]   =  0.00404301  
    score[1]   =  0.00666579  
    score[2]   =  0.989291    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_03.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_03.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:49:16.835510  2409 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_03.bmp result:
    score[0]   =  0.0105812   
    score[1]   =  0.0369319   
    score[2]   =  0.952487    
xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_04.bmp
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_04.bmp
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1210 16:49:21.233657  2410 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_04.bmp result:
    score[0]   =  0.124399    
    score[1]   =  0.159732    
    score[2]   =  0.715869    


右旋回は推論 5 回中 5 回とも当たりだ。

現在の推論結果は 15 回推論して、10 回当たりなので、10 / 15 = 0.76 で 76 % の正答率だった。
大体これで行けているのかも知れない?

(追記)
Vitis-AI/examples/Custom_OP_Demo/tensorflow2_example/deployment/cpp の tf2_custom_op_graph_runner.cpp は bmp ファイルを読めるようになっていないので、修正した。
22 行目の

std::vector supported_ext = {".jpg", ".png"};

std::vector supported_ext = {".jpg", ".png", ".bmp"};

に変更して、
bash build.sh
コマンドでコンパイルして、

tf2_custom_op_graph_runner

を再度生成した。
  1. 2022年12月11日 09:55 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する4

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する3”の続き。

白線間走行用CNNをKerasで学習する”で学習した白線間走行用 CNN を Vitis-AI のカスタム OP ワークフローで動作させてみたいということで、前回は、量子化とコンパイルを行って、XMODEL を生成した。今回は、XMODEL と テスト用画像を kv260 の Petalinux 2022.1 にアップロードして推論したが、結果が間違っているようだった。

tf2_curve_line.xmodel と 3 個のテスト用画像を Petalinux 2022.1 の ~/tensorflow2_example に FileZilla でアップロードした。
Custom_OP_Workflow_46_221207.png

まずは、kv260 の Petalinux 2022.1 の環境を設定した。
cd ~/kv260_median/dpu
sudo mkdir -p /run/media/mmcblk0p1/
sudo cp dpu.xclbin /run/media/mmcblk0p1/
sudo xmutil unloadapp
sudo xmutil loadapp dpuprj
cd ~/tensorflow2_example/deployment/cpp

Custom_OP_Workflow_46_221208.png

走行方向の判定は直進が score[1]、左旋回が socre[0]、右旋回が score[2] が最大になる予定だ。(”白線追従走行用畳み込みニューラルネットワーク・システムの製作6(実機で確認2)”参照)

まずは直進の画像の straight_RED_rect5_24.jpg を推論してみたところ、score[2] が最大値となった。右旋回となった。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect5_24.jpg
Custom_OP_Workflow_47_221208.png

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/straight_RED_rect5_24.jpg
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/straight_RED_rect5_24.jpg
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1208 04:47:28.646189  1217 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/straight_RED_rect5_24.jpg result:
    score[0]   =  0.00664835  
    score[1]   =  0.00664835  
    score[2]   =  0.986703    



次に、左旋回画像の left_turn_RED_rect0_00.jpg を推論したところ、やはり右旋回という結果だった。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_00.jpg
Custom_OP_Workflow_48_221208.png

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/left_turn_RED_rect0_00.jpg
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/left_turn_RED_rect0_00.jpg
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1208 04:47:59.089350  1248 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/left_turn_RED_rect0_00.jpg result:
    score[0]   =  0.0108675   
    score[1]   =  0.0108675   
    score[2]   =  0.978265    


最後に右旋回の画像の right_turn_RED_rect0_00.jpg を推論してみたところ右旋回という結果だった。これは正しい。
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_00.jpg
Custom_OP_Workflow_49_221208.png

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_curve_line.xmodel ~/tensorflow2_example/right_turn_RED_rect0_00.jpg
model_file: /home/petalinux/tensorflow2_example/tf2_curve_line.xmodel
image_path: /home/petalinux/tensorflow2_example/right_turn_RED_rect0_00.jpg
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1208 04:48:13.153605  1261 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/right_turn_RED_rect0_00.jpg result:
    score[0]   =  0.0158762   
    score[1]   =  0.11731     
    score[2]   =  0.866813    


全ての推論結果が右旋回という結果が出た。これは推論がおかしいと思う。
もう一度学習を見直してみたい。

後で、テスト用画像を貼っておく。
  1. 2022年12月10日 05:03 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する3

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する2”の続き。

白線間走行用CNNをKerasで学習する”で学習した白線間走行用 CNN を Vitis-AI のカスタム OP ワークフローで動作させてみたいということで、前回は、train_eval_line.py による学習を行った。今回は、量子化とコンパイルを行って、XMODEL を生成した。

量子化を行った。
python quantize_curve_line.py
Custom_OP_Workflow_40_221208.png
Custom_OP_Workflow_41_221208.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > python quantize_curve_line.py 
2022-12-08 03:06:20.049079: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-12-08 03:06:20.049101: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2.8.0
2.8.0
2022-12-08 03:06:21.606180: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-12-08 03:06:21.606207: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-12-08 03:06:21.606233: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:163] no NVIDIA GPU device is present: /dev/nvidia0 does not exist
2022-12-08 03:06:21.606406: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 10, 56, 1)]       0         
                                                                 
 conv2d (Conv2D)             (None, 6, 52, 2)          52        
                                                                 
 max_pooling2d (MaxPooling2D  (None, 3, 26, 2)         0         
 )                                                               
                                                                 
 custom_layer (Mylayer)      (None, 3, 26, 2)          156       
                                                                 
 flatten (Flatten)           (None, 156)               0         
                                                                 
 dense (Dense)               (None, 100)               15700     
                                                                 
 dense_1 (Dense)             (None, 3)                 303       
                                                                 
=================================================================
Total params: 16,211
Trainable params: 16,211
Non-trainable params: 0
_________________________________________________________________
[VAI INFO] Update custom_layer_type: ['Mylayer']
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Start CrossLayerEqualization...
 1/10 [==>...........................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 2/10 [=====>........................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 3/10 [========>.....................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 4/10 [===========>..................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 5/10 [==============>...............] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 6/10 [=================>............] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 7/10 [====================>.........] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 8/10 [=======================>......] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 9/10 [==========================>...] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
10/10 [==============================] - 1s 66ms/step
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] CrossLayerEqualization Done.
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Layer custom_layer(<class 'train_eval_line.Mylayer'>) is not supported by DPU, it will not be quantized and may be mapped to run on CPU or other IPs. Please see User Guide for list of supported operations and APIs of vai_q_tensorflow2.
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Start Quantize Calibration...
830/830 [==============================] - 5s 5ms/step
[VAI INFO] Quantize Calibration Done.
[VAI INFO] Start Post-Quant Model Refinement...
[VAI INFO] Start Quantize Position Ajustment...
[VAI INFO] Quantize Position Ajustment Done.
[VAI INFO] Start Getting Shape Information...
[VAI INFO] Getting model layer shape information
[VAI INFO] Getting Shape Information Done.
[VAI INFO] Post-Quant Model Refninement Done.
[VAI INFO] Start Model Finalization...
[VAI INFO] Model Finalization Done.
[VAI INFO] Quantization Finished.
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.

***************** Summary *****************
Quantized model is saved in  ./quantized/quantized_curve_line.h5


コンパイルを行った。
vai_c_tensorflow2 -m ./quantized/quantized_curve_line.h5 -a ../kv260_myarch.json -o ./ -n tf2_curve_line
tf2_curve_line.xmodel が生成された。
Custom_OP_Workflow_42_221208.png
Custom_OP_Workflow_43_221208.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > vai_c_tensorflow2 -m ./quantized/quantized_curve_line.h5 -a ../kv260_myarch.json -o ./ -n tf2_curve_line
**************************************************
* VITIS_AI Compilation - Xilinx Inc.
**************************************************
[INFO] Namespace(batchsize=1, inputs_shape=None, layout='NHWC', model_files=['./quantized/quantized_curve_line.h5'], model_type='tensorflow2', named_inputs_shape=None, out_filename='/tmp/tf2_curve_line_0x101000017010406_org.xmodel', proto=None)
[INFO] tensorflow2 model: /workspace/tf2_custom_op_demo/quantized/quantized_curve_line.h5
[INFO] keras version: 2.8.0
[INFO] Tensorflow Keras model type: functional
/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib/python3.7/site-packages/xnnc/translator/tensorflow_translator.py:2537: H5pyDeprecationWarning: dataset.value has been deprecated. Use dataset[()] instead.
  layer['config']['shape'] = h5f['optimizer_weights'][name+':0'].value.tolist()
[INFO] parse raw model     :100%|█| 12/12 [00:00<00:00, 14873.42it/s]           
[INFO] infer shape (NHWC)  :100%|█| 21/21 [00:00<00:00, 22003.59it/s]           
[INFO] perform level-0 opt :100%|█| 2/2 [00:00<00:00, 698.64it/s]               
[INFO] perform level-1 opt :100%|█| 2/2 [00:00<00:00, 2537.39it/s]              
[INFO] generate xmodel     :  0%| | 0/21 [00:00<?, ?it/s]                       WARNING: Logging before InitGoogleLogging() is written to STDERR
W1208 03:08:54.900501  2409 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
[INFO] generate xmodel     :100%|█| 21/21 [00:00<00:00, 5217.72it/s]            
[INFO] dump xmodel: /tmp/tf2_curve_line_0x101000017010406_org.xmodel
[UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
[UNILOG][INFO] Compile mode: dpu
[UNILOG][INFO] Debug mode: function
[UNILOG][INFO] Target architecture: DPUCZDX8G_ISA1_B3136_0101000017010406
[UNILOG][INFO] Graph name: model, with op num: 29
[UNILOG][INFO] Begin to compile...
[UNILOG][INFO] Total device subgraph number 5, DPU subgraph number 2
[UNILOG][INFO] Compile done.
[UNILOG][INFO] The meta json is saved to "/workspace/tf2_custom_op_demo/./meta.json"
[UNILOG][INFO] The compiled xmodel is saved to "/workspace/tf2_custom_op_demo/.//tf2_curve_line.xmodel"
[UNILOG][INFO] The compiled xmodel's md5sum is 47bfeeb7ac6e503ec52b1bd314a5875c, and has been saved to "/workspace/tf2_custom_op_demo/./md5sum.txt"


netronで tf2_curve_line.xmodel の構成を見た。
Custom_OP_Workflow_44_221208.pngCustom_OP_Workflow_45_221208.png

  1. 2022年12月09日 04:53 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する2

自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する1”の続き。

白線間走行用CNNをKerasで学習する”で学習した白線間走行用 CNN を Vitis-AI のカスタム OP ワークフローで動作させてみたいということで、前回は、修正した train_eval_line.py と quntize_curve_line.py を貼っておく。更に、train_curve_run_image、train_curve_run_label、test_curve_run_image、test_curve_run_label、学習用データとテスト・データを読み込む curve_dataset.py を Vitis-AI/tf2_custom_op_demo ディレクトリにコピーした。今回は、train_eval_line.py による学習を行った。

train_eval_line.py による学習を行う。
pytyon train_eval_line.py
Custom_OP_Workflow_38_221207.png
Custom_OP_Workflow_39_221207.png

浮動小数点数モデルの精度は 0.954 程度だった。

ログを貼っておく。

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > python train_eval_line.py
2022-12-08 02:30:50.225265: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-12-08 02:30:50.225295: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2.8.0
2022-12-08 02:30:52.560898: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-12-08 02:30:52.560990: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-12-08 02:30:52.561056: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:163] no NVIDIA GPU device is present: /dev/nvidia0 does not exist
2022-12-08 02:30:52.561320: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 10, 56, 1)]       0         
                                                                 
 conv2d (Conv2D)             (None, 6, 52, 2)          52        
                                                                 
 max_pooling2d (MaxPooling2D  (None, 3, 26, 2)         0         
 )                                                               
                                                                 
 custom_layer (Mylayer)      (None, 3, 26, 2)          156       
                                                                 
 flatten (Flatten)           (None, 156)               0         
                                                                 
 dense (Dense)               (None, 100)               15700     
                                                                 
 dense_1 (Dense)             (None, 3)                 303       
                                                                 
=================================================================
Total params: 16,211
Trainable params: 16,211
Non-trainable params: 0
_________________________________________________________________

Epoch 1/20
   1/1083 [..............................] - ETA: 7:21 - loss: 0.6856 - accuracy  15/1083 [..............................] - ETA: 3s - loss: 0.6058 - accuracy:   31/1083 [..............................] - ETA: 3s - loss: 0.5595 - accuracy:   46/1083 [>.............................] - ETA: 3s - loss: 0.5350 - accuracy:   62/1083 [>.............................] - ETA: 3s - loss: 0.5056 - accuracy:   77/1083 [=>............................] - ETA: 3s - loss: 0.4778 - accuracy:   92/1083 [=>............................] - ETA: 3s - loss: 0.4577 - accuracy:  107/1083 [=>............................] - ETA: 3s - loss: 0.4427 - accuracy:  123/1083 [==>...........................] - ETA: 3s - loss: 0.4289 - accuracy:  139/1083 [==>...........................] - ETA: 3s - loss: 0.4196 - accuracy:  155/1083 [===>..........................] - ETA: 3s - loss: 0.4084 - accuracy:  170/1083 [===>..........................] - ETA: 3s - loss: 0.4015 - accuracy:  186/1083 [====>.........................] - ETA: 3s - loss: 0.3919 - accuracy:  202/1083 [====>.........................] - ETA: 2s - loss: 0.3844 - accuracy:  218/1083 [=====>........................] - ETA: 2s - loss: 0.3770 - accuracy:  232/1083 [=====>........................] - ETA: 2s - loss: 0.3731 - accuracy:  246/1083 [=====>........................] - ETA: 2s - loss: 0.3672 - accuracy:  261/1083 [======>.......................] - ETA: 2s - loss: 0.3647 - accuracy:  276/1083 [======>.......................] - ETA: 2s - loss: 0.3622 - accuracy:  291/1083 [=======>......................] - ETA: 2s - loss: 0.3582 - accuracy:  306/1083 [=======>......................] - ETA: 2s - loss: 0.3540 - accuracy:  322/1083 [=======>......................] - ETA: 2s - loss: 0.3521 - accuracy:  337/1083 [========>.....................] - ETA: 2s - loss: 0.3490 - accuracy:  353/1083 [========>.....................] - ETA: 2s - loss: 0.3458 - accuracy:  368/1083 [=========>....................] - ETA: 2s - loss: 0.3430 - accuracy:  383/1083 [=========>....................] - ETA: 2s - loss: 0.3394 - accuracy:  397/1083 [=========>....................] - ETA: 2s - loss: 0.3381 - accuracy:  411/1083 [==========>...................] - ETA: 2s - loss: 0.3365 - accuracy:  427/1083 [==========>...................] - ETA: 2s - loss: 0.3348 - accuracy:  442/1083 [===========>..................] - ETA: 2s - loss: 0.3331 - accuracy:  458/1083 [===========>..................] - ETA: 2s - loss: 0.3302 - accuracy:  474/1083 [============>.................] - ETA: 2s - loss: 0.3277 - accuracy:  490/1083 [============>.................] - ETA: 2s - loss: 0.3258 - accuracy:  506/1083 [=============>................] - ETA: 1s - loss: 0.3231 - accuracy:  522/1083 [=============>................] - ETA: 1s - loss: 0.3205 - accuracy:  538/1083 [=============>................] - ETA: 1s - loss: 0.3180 - accuracy:  552/1083 [==============>...............] - ETA: 1s - loss: 0.3154 - accuracy:  568/1083 [==============>...............] - ETA: 1s - loss: 0.3130 - accuracy:  583/1083 [===============>..............] - ETA: 1s - loss: 0.3118 - accuracy:  599/1083 [===============>..............] - ETA: 1s - loss: 0.3101 - accuracy:  614/1083 [================>.............] - ETA: 1s - loss: 0.3080 - accuracy:  629/1083 [================>.............] - ETA: 1s - loss: 0.3060 - accuracy:  644/1083 [================>.............] - ETA: 1s - loss: 0.3040 - accuracy:  660/1083 [=================>............] - ETA: 1s - loss: 0.3024 - accuracy:  674/1083 [=================>............] - ETA: 1s - loss: 0.3003 - accuracy:  689/1083 [==================>...........] - ETA: 1s - loss: 0.2979 - accuracy:  704/1083 [==================>...........] - ETA: 1s - loss: 0.2959 - accuracy:  720/1083 [==================>...........] - ETA: 1s - loss: 0.2944 - accuracy:  735/1083 [===================>..........] - ETA: 1s - loss: 0.2927 - accuracy:  752/1083 [===================>..........] - ETA: 1s - loss: 0.2906 - accuracy:  768/1083 [====================>.........] - ETA: 1s - loss: 0.2894 - accuracy:  784/1083 [====================>.........] - ETA: 1s - loss: 0.2881 - accuracy:  798/1083 [=====================>........] - ETA: 0s - loss: 0.2865 - accuracy:  814/1083 [=====================>........] - ETA: 0s - loss: 0.2852 - accuracy:  828/1083 [=====================>........] - ETA: 0s - loss: 0.2836 - accuracy:  842/1083 [======================>.......] - ETA: 0s - loss: 0.2822 - accuracy:  857/1083 [======================>.......] - ETA: 0s - loss: 0.2807 - accuracy:  873/1083 [=======================>......] - ETA: 0s - loss: 0.2792 - accuracy:  888/1083 [=======================>......] - ETA: 0s - loss: 0.2774 - accuracy:  904/1083 [========================>.....] - ETA: 0s - loss: 0.2759 - accuracy:  918/1083 [========================>.....] - ETA: 0s - loss: 0.2748 - accuracy:  934/1083 [========================>.....] - ETA: 0s - loss: 0.2732 - accuracy:  950/1083 [=========================>....] - ETA: 0s - loss: 0.2716 - accuracy:  965/1083 [=========================>....] - ETA: 0s - loss: 0.2704 - accuracy:  981/1083 [==========================>...] - ETA: 0s - loss: 0.2689 - accuracy:  997/1083 [==========================>...] - ETA: 0s - loss: 0.2671 - accuracy: 1012/1083 [===========================>..] - ETA: 0s - loss: 0.2657 - accuracy: 1028/1083 [===========================>..] - ETA: 0s - loss: 0.2638 - accuracy: 1044/1083 [===========================>..] - ETA: 0s - loss: 0.2622 - accuracy: 1060/1083 [============================>.] - ETA: 0s - loss: 0.2604 - accuracy: 1076/1083 [============================>.] - ETA: 0s - loss: 0.2590 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.2583 - accuracy: 0.8406
Epoch 2/20
   1/1083 [..............................] - ETA: 3s - loss: 0.1257 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.1498 - accuracy:   31/1083 [..............................] - ETA: 3s - loss: 0.1515 - accuracy:   46/1083 [>.............................] - ETA: 3s - loss: 0.1571 - accuracy:   62/1083 [>.............................] - ETA: 3s - loss: 0.1571 - accuracy:   78/1083 [=>............................] - ETA: 3s - loss: 0.1560 - accuracy:   93/1083 [=>............................] - ETA: 3s - loss: 0.1565 - accuracy:  109/1083 [==>...........................] - ETA: 3s - loss: 0.1505 - accuracy:  124/1083 [==>...........................] - ETA: 3s - loss: 0.1482 - accuracy:  140/1083 [==>...........................] - ETA: 3s - loss: 0.1469 - accuracy:  156/1083 [===>..........................] - ETA: 3s - loss: 0.1463 - accuracy:  172/1083 [===>..........................] - ETA: 3s - loss: 0.1459 - accuracy:  186/1083 [====>.........................] - ETA: 2s - loss: 0.1456 - accuracy:  200/1083 [====>.........................] - ETA: 2s - loss: 0.1462 - accuracy:  215/1083 [====>.........................] - ETA: 2s - loss: 0.1446 - accuracy:  231/1083 [=====>........................] - ETA: 2s - loss: 0.1435 - accuracy:  247/1083 [=====>........................] - ETA: 2s - loss: 0.1426 - accuracy:  263/1083 [======>.......................] - ETA: 2s - loss: 0.1415 - accuracy:  278/1083 [======>.......................] - ETA: 2s - loss: 0.1412 - accuracy:  294/1083 [=======>......................] - ETA: 2s - loss: 0.1397 - accuracy:  310/1083 [=======>......................] - ETA: 2s - loss: 0.1397 - accuracy:  324/1083 [=======>......................] - ETA: 2s - loss: 0.1388 - accuracy:  339/1083 [========>.....................] - ETA: 2s - loss: 0.1378 - accuracy:  354/1083 [========>.....................] - ETA: 2s - loss: 0.1374 - accuracy:  369/1083 [=========>....................] - ETA: 2s - loss: 0.1366 - accuracy:  385/1083 [=========>....................] - ETA: 2s - loss: 0.1361 - accuracy:  401/1083 [==========>...................] - ETA: 2s - loss: 0.1356 - accuracy:  416/1083 [==========>...................] - ETA: 2s - loss: 0.1352 - accuracy:  429/1083 [==========>...................] - ETA: 2s - loss: 0.1351 - accuracy:  443/1083 [===========>..................] - ETA: 2s - loss: 0.1349 - accuracy:  457/1083 [===========>..................] - ETA: 2s - loss: 0.1337 - accuracy:  472/1083 [============>.................] - ETA: 2s - loss: 0.1331 - accuracy:  485/1083 [============>.................] - ETA: 2s - loss: 0.1330 - accuracy:  500/1083 [============>.................] - ETA: 1s - loss: 0.1333 - accuracy:  516/1083 [=============>................] - ETA: 1s - loss: 0.1333 - accuracy:  532/1083 [=============>................] - ETA: 1s - loss: 0.1326 - accuracy:  548/1083 [==============>...............] - ETA: 1s - loss: 0.1318 - accuracy:  564/1083 [==============>...............] - ETA: 1s - loss: 0.1312 - accuracy:  579/1083 [===============>..............] - ETA: 1s - loss: 0.1308 - accuracy:  594/1083 [===============>..............] - ETA: 1s - loss: 0.1304 - accuracy:  610/1083 [===============>..............] - ETA: 1s - loss: 0.1299 - accuracy:  626/1083 [================>.............] - ETA: 1s - loss: 0.1296 - accuracy:  642/1083 [================>.............] - ETA: 1s - loss: 0.1294 - accuracy:  658/1083 [=================>............] - ETA: 1s - loss: 0.1286 - accuracy:  674/1083 [=================>............] - ETA: 1s - loss: 0.1285 - accuracy:  689/1083 [==================>...........] - ETA: 1s - loss: 0.1280 - accuracy:  705/1083 [==================>...........] - ETA: 1s - loss: 0.1276 - accuracy:  721/1083 [==================>...........] - ETA: 1s - loss: 0.1275 - accuracy:  737/1083 [===================>..........] - ETA: 1s - loss: 0.1273 - accuracy:  751/1083 [===================>..........] - ETA: 1s - loss: 0.1270 - accuracy:  767/1083 [====================>.........] - ETA: 1s - loss: 0.1267 - accuracy:  782/1083 [====================>.........] - ETA: 1s - loss: 0.1267 - accuracy:  798/1083 [=====================>........] - ETA: 0s - loss: 0.1264 - accuracy:  813/1083 [=====================>........] - ETA: 0s - loss: 0.1257 - accuracy:  828/1083 [=====================>........] - ETA: 0s - loss: 0.1255 - accuracy:  843/1083 [======================>.......] - ETA: 0s - loss: 0.1251 - accuracy:  859/1083 [======================>.......] - ETA: 0s - loss: 0.1246 - accuracy:  874/1083 [=======================>......] - ETA: 0s - loss: 0.1240 - accuracy:  889/1083 [=======================>......] - ETA: 0s - loss: 0.1236 - accuracy:  905/1083 [========================>.....] - ETA: 0s - loss: 0.1232 - accuracy:  921/1083 [========================>.....] - ETA: 0s - loss: 0.1227 - accuracy:  935/1083 [========================>.....] - ETA: 0s - loss: 0.1221 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.1216 - accuracy:  963/1083 [=========================>....] - ETA: 0s - loss: 0.1212 - accuracy:  977/1083 [==========================>...] - ETA: 0s - loss: 0.1209 - accuracy:  992/1083 [==========================>...] - ETA: 0s - loss: 0.1202 - accuracy: 1007/1083 [==========================>...] - ETA: 0s - loss: 0.1202 - accuracy: 1022/1083 [===========================>..] - ETA: 0s - loss: 0.1200 - accuracy: 1038/1083 [===========================>..] - ETA: 0s - loss: 0.1194 - accuracy: 1054/1083 [============================>.] - ETA: 0s - loss: 0.1188 - accuracy: 1069/1083 [============================>.] - ETA: 0s - loss: 0.1183 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.1178 - accuracy: 0.9377
Epoch 3/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0658 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.0942 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0839 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0845 - accuracy:   63/1083 [>.............................] - ETA: 3s - loss: 0.0827 - accuracy:   77/1083 [=>............................] - ETA: 3s - loss: 0.0807 - accuracy:   93/1083 [=>............................] - ETA: 3s - loss: 0.0823 - accuracy:  109/1083 [==>...........................] - ETA: 3s - loss: 0.0842 - accuracy:  125/1083 [==>...........................] - ETA: 3s - loss: 0.0869 - accuracy:  140/1083 [==>...........................] - ETA: 3s - loss: 0.0883 - accuracy:  155/1083 [===>..........................] - ETA: 3s - loss: 0.0893 - accuracy:  170/1083 [===>..........................] - ETA: 3s - loss: 0.0878 - accuracy:  186/1083 [====>.........................] - ETA: 3s - loss: 0.0879 - accuracy:  201/1083 [====>.........................] - ETA: 2s - loss: 0.0875 - accuracy:  217/1083 [=====>........................] - ETA: 2s - loss: 0.0878 - accuracy:  232/1083 [=====>........................] - ETA: 2s - loss: 0.0872 - accuracy:  248/1083 [=====>........................] - ETA: 2s - loss: 0.0874 - accuracy:  263/1083 [======>.......................] - ETA: 2s - loss: 0.0876 - accuracy:  279/1083 [======>.......................] - ETA: 2s - loss: 0.0870 - accuracy:  293/1083 [=======>......................] - ETA: 2s - loss: 0.0869 - accuracy:  307/1083 [=======>......................] - ETA: 2s - loss: 0.0876 - accuracy:  320/1083 [=======>......................] - ETA: 2s - loss: 0.0878 - accuracy:  336/1083 [========>.....................] - ETA: 2s - loss: 0.0874 - accuracy:  351/1083 [========>.....................] - ETA: 2s - loss: 0.0866 - accuracy:  367/1083 [=========>....................] - ETA: 2s - loss: 0.0858 - accuracy:  382/1083 [=========>....................] - ETA: 2s - loss: 0.0845 - accuracy:  398/1083 [==========>...................] - ETA: 2s - loss: 0.0840 - accuracy:  413/1083 [==========>...................] - ETA: 2s - loss: 0.0843 - accuracy:  428/1083 [==========>...................] - ETA: 2s - loss: 0.0837 - accuracy:  442/1083 [===========>..................] - ETA: 2s - loss: 0.0835 - accuracy:  457/1083 [===========>..................] - ETA: 2s - loss: 0.0835 - accuracy:  470/1083 [============>.................] - ETA: 2s - loss: 0.0833 - accuracy:  486/1083 [============>.................] - ETA: 2s - loss: 0.0830 - accuracy:  501/1083 [============>.................] - ETA: 1s - loss: 0.0823 - accuracy:  516/1083 [=============>................] - ETA: 1s - loss: 0.0817 - accuracy:  531/1083 [=============>................] - ETA: 1s - loss: 0.0813 - accuracy:  546/1083 [==============>...............] - ETA: 1s - loss: 0.0808 - accuracy:  559/1083 [==============>...............] - ETA: 1s - loss: 0.0809 - accuracy:  572/1083 [==============>...............] - ETA: 1s - loss: 0.0808 - accuracy:  585/1083 [===============>..............] - ETA: 1s - loss: 0.0803 - accuracy:  599/1083 [===============>..............] - ETA: 1s - loss: 0.0802 - accuracy:  613/1083 [===============>..............] - ETA: 1s - loss: 0.0800 - accuracy:  627/1083 [================>.............] - ETA: 1s - loss: 0.0801 - accuracy:  642/1083 [================>.............] - ETA: 1s - loss: 0.0799 - accuracy:  657/1083 [=================>............] - ETA: 1s - loss: 0.0800 - accuracy:  672/1083 [=================>............] - ETA: 1s - loss: 0.0796 - accuracy:  688/1083 [==================>...........] - ETA: 1s - loss: 0.0799 - accuracy:  704/1083 [==================>...........] - ETA: 1s - loss: 0.0800 - accuracy:  720/1083 [==================>...........] - ETA: 1s - loss: 0.0797 - accuracy:  736/1083 [===================>..........] - ETA: 1s - loss: 0.0797 - accuracy:  752/1083 [===================>..........] - ETA: 1s - loss: 0.0796 - accuracy:  768/1083 [====================>.........] - ETA: 1s - loss: 0.0794 - accuracy:  783/1083 [====================>.........] - ETA: 1s - loss: 0.0795 - accuracy:  798/1083 [=====================>........] - ETA: 0s - loss: 0.0792 - accuracy:  812/1083 [=====================>........] - ETA: 0s - loss: 0.0790 - accuracy:  824/1083 [=====================>........] - ETA: 0s - loss: 0.0788 - accuracy:  834/1083 [======================>.......] - ETA: 0s - loss: 0.0789 - accuracy:  845/1083 [======================>.......] - ETA: 0s - loss: 0.0788 - accuracy:  858/1083 [======================>.......] - ETA: 0s - loss: 0.0787 - accuracy:  872/1083 [=======================>......] - ETA: 0s - loss: 0.0784 - accuracy:  885/1083 [=======================>......] - ETA: 0s - loss: 0.0782 - accuracy:  898/1083 [=======================>......] - ETA: 0s - loss: 0.0780 - accuracy:  911/1083 [========================>.....] - ETA: 0s - loss: 0.0779 - accuracy:  924/1083 [========================>.....] - ETA: 0s - loss: 0.0778 - accuracy:  931/1083 [========================>.....] - ETA: 0s - loss: 0.0777 - accuracy:  939/1083 [=========================>....] - ETA: 0s - loss: 0.0777 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.0775 - accuracy:  958/1083 [=========================>....] - ETA: 0s - loss: 0.0773 - accuracy:  966/1083 [=========================>....] - ETA: 0s - loss: 0.0770 - accuracy:  976/1083 [==========================>...] - ETA: 0s - loss: 0.0770 - accuracy:  984/1083 [==========================>...] - ETA: 0s - loss: 0.0770 - accuracy:  991/1083 [==========================>...] - ETA: 0s - loss: 0.0768 - accuracy: 1000/1083 [==========================>...] - ETA: 0s - loss: 0.0766 - accuracy: 1012/1083 [===========================>..] - ETA: 0s - loss: 0.0765 - accuracy: 1020/1083 [===========================>..] - ETA: 0s - loss: 0.0765 - accuracy: 1030/1083 [===========================>..] - ETA: 0s - loss: 0.0764 - accuracy: 1040/1083 [===========================>..] - ETA: 0s - loss: 0.0763 - accuracy: 1048/1083 [============================>.] - ETA: 0s - loss: 0.0763 - accuracy: 1057/1083 [============================>.] - ETA: 0s - loss: 0.0761 - accuracy: 1065/1083 [============================>.] - ETA: 0s - loss: 0.0761 - accuracy: 1074/1083 [============================>.] - ETA: 0s - loss: 0.0759 - accuracy: 1083/1083 [==============================] - ETA: 0s - loss: 0.0759 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0759 - accuracy: 0.9612
Epoch 4/20
   1/1083 [..............................] - ETA: 7s - loss: 0.0091 - accuracy:   11/1083 [..............................] - ETA: 5s - loss: 0.0536 - accuracy:   22/1083 [..............................] - ETA: 5s - loss: 0.0535 - accuracy:   32/1083 [..............................] - ETA: 5s - loss: 0.0607 - accuracy:   42/1083 [>.............................] - ETA: 5s - loss: 0.0642 - accuracy:   54/1083 [>.............................] - ETA: 5s - loss: 0.0607 - accuracy:   65/1083 [>.............................] - ETA: 5s - loss: 0.0589 - accuracy:   76/1083 [=>............................] - ETA: 4s - loss: 0.0601 - accuracy:   88/1083 [=>............................] - ETA: 4s - loss: 0.0602 - accuracy:  100/1083 [=>............................] - ETA: 4s - loss: 0.0608 - accuracy:  113/1083 [==>...........................] - ETA: 4s - loss: 0.0610 - accuracy:  125/1083 [==>...........................] - ETA: 4s - loss: 0.0599 - accuracy:  138/1083 [==>...........................] - ETA: 4s - loss: 0.0596 - accuracy:  150/1083 [===>..........................] - ETA: 4s - loss: 0.0600 - accuracy:  163/1083 [===>..........................] - ETA: 4s - loss: 0.0599 - accuracy:  176/1083 [===>..........................] - ETA: 4s - loss: 0.0609 - accuracy:  190/1083 [====>.........................] - ETA: 3s - loss: 0.0610 - accuracy:  204/1083 [====>.........................] - ETA: 3s - loss: 0.0614 - accuracy:  219/1083 [=====>........................] - ETA: 3s - loss: 0.0610 - accuracy:  233/1083 [=====>........................] - ETA: 3s - loss: 0.0614 - accuracy:  248/1083 [=====>........................] - ETA: 3s - loss: 0.0609 - accuracy:  262/1083 [======>.......................] - ETA: 3s - loss: 0.0606 - accuracy:  277/1083 [======>.......................] - ETA: 3s - loss: 0.0601 - accuracy:  291/1083 [=======>......................] - ETA: 3s - loss: 0.0600 - accuracy:  305/1083 [=======>......................] - ETA: 3s - loss: 0.0596 - accuracy:  316/1083 [=======>......................] - ETA: 3s - loss: 0.0599 - accuracy:  331/1083 [========>.....................] - ETA: 3s - loss: 0.0598 - accuracy:  346/1083 [========>.....................] - ETA: 2s - loss: 0.0595 - accuracy:  360/1083 [========>.....................] - ETA: 2s - loss: 0.0592 - accuracy:  374/1083 [=========>....................] - ETA: 2s - loss: 0.0586 - accuracy:  388/1083 [=========>....................] - ETA: 2s - loss: 0.0590 - accuracy:  402/1083 [==========>...................] - ETA: 2s - loss: 0.0586 - accuracy:  415/1083 [==========>...................] - ETA: 2s - loss: 0.0588 - accuracy:  428/1083 [==========>...................] - ETA: 2s - loss: 0.0589 - accuracy:  442/1083 [===========>..................] - ETA: 2s - loss: 0.0586 - accuracy:  457/1083 [===========>..................] - ETA: 2s - loss: 0.0582 - accuracy:  472/1083 [============>.................] - ETA: 2s - loss: 0.0579 - accuracy:  486/1083 [============>.................] - ETA: 2s - loss: 0.0578 - accuracy:  503/1083 [============>.................] - ETA: 2s - loss: 0.0577 - accuracy:  517/1083 [=============>................] - ETA: 2s - loss: 0.0580 - accuracy:  528/1083 [=============>................] - ETA: 2s - loss: 0.0576 - accuracy:  537/1083 [=============>................] - ETA: 2s - loss: 0.0576 - accuracy:  546/1083 [==============>...............] - ETA: 2s - loss: 0.0576 - accuracy:  555/1083 [==============>...............] - ETA: 2s - loss: 0.0576 - accuracy:  565/1083 [==============>...............] - ETA: 2s - loss: 0.0574 - accuracy:  575/1083 [==============>...............] - ETA: 2s - loss: 0.0574 - accuracy:  587/1083 [===============>..............] - ETA: 2s - loss: 0.0571 - accuracy:  596/1083 [===============>..............] - ETA: 1s - loss: 0.0569 - accuracy:  607/1083 [===============>..............] - ETA: 1s - loss: 0.0569 - accuracy:  615/1083 [================>.............] - ETA: 1s - loss: 0.0568 - accuracy:  623/1083 [================>.............] - ETA: 1s - loss: 0.0569 - accuracy:  636/1083 [================>.............] - ETA: 1s - loss: 0.0570 - accuracy:  648/1083 [================>.............] - ETA: 1s - loss: 0.0568 - accuracy:  661/1083 [=================>............] - ETA: 1s - loss: 0.0568 - accuracy:  673/1083 [=================>............] - ETA: 1s - loss: 0.0565 - accuracy:  686/1083 [==================>...........] - ETA: 1s - loss: 0.0564 - accuracy:  700/1083 [==================>...........] - ETA: 1s - loss: 0.0560 - accuracy:  713/1083 [==================>...........] - ETA: 1s - loss: 0.0557 - accuracy:  725/1083 [===================>..........] - ETA: 1s - loss: 0.0556 - accuracy:  737/1083 [===================>..........] - ETA: 1s - loss: 0.0553 - accuracy:  748/1083 [===================>..........] - ETA: 1s - loss: 0.0552 - accuracy:  760/1083 [====================>.........] - ETA: 1s - loss: 0.0551 - accuracy:  772/1083 [====================>.........] - ETA: 1s - loss: 0.0550 - accuracy:  784/1083 [====================>.........] - ETA: 1s - loss: 0.0552 - accuracy:  796/1083 [=====================>........] - ETA: 1s - loss: 0.0552 - accuracy:  808/1083 [=====================>........] - ETA: 1s - loss: 0.0553 - accuracy:  819/1083 [=====================>........] - ETA: 1s - loss: 0.0552 - accuracy:  835/1083 [======================>.......] - ETA: 1s - loss: 0.0551 - accuracy:  850/1083 [======================>.......] - ETA: 0s - loss: 0.0550 - accuracy:  866/1083 [======================>.......] - ETA: 0s - loss: 0.0549 - accuracy:  880/1083 [=======================>......] - ETA: 0s - loss: 0.0550 - accuracy:  895/1083 [=======================>......] - ETA: 0s - loss: 0.0549 - accuracy:  910/1083 [========================>.....] - ETA: 0s - loss: 0.0548 - accuracy:  926/1083 [========================>.....] - ETA: 0s - loss: 0.0549 - accuracy:  942/1083 [=========================>....] - ETA: 0s - loss: 0.0547 - accuracy:  959/1083 [=========================>....] - ETA: 0s - loss: 0.0546 - accuracy:  975/1083 [==========================>...] - ETA: 0s - loss: 0.0544 - accuracy:  990/1083 [==========================>...] - ETA: 0s - loss: 0.0543 - accuracy: 1004/1083 [==========================>...] - ETA: 0s - loss: 0.0541 - accuracy: 1018/1083 [===========================>..] - ETA: 0s - loss: 0.0540 - accuracy: 1032/1083 [===========================>..] - ETA: 0s - loss: 0.0538 - accuracy: 1047/1083 [============================>.] - ETA: 0s - loss: 0.0536 - accuracy: 1059/1083 [============================>.] - ETA: 0s - loss: 0.0537 - accuracy: 1075/1083 [============================>.] - ETA: 0s - loss: 0.0537 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0537 - accuracy: 0.9720
Epoch 5/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0340 - accuracy:   17/1083 [..............................] - ETA: 3s - loss: 0.0334 - accuracy:   33/1083 [..............................] - ETA: 3s - loss: 0.0339 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0383 - accuracy:   61/1083 [>.............................] - ETA: 3s - loss: 0.0386 - accuracy:   74/1083 [=>............................] - ETA: 3s - loss: 0.0388 - accuracy:   84/1083 [=>............................] - ETA: 3s - loss: 0.0386 - accuracy:   94/1083 [=>............................] - ETA: 3s - loss: 0.0400 - accuracy:  102/1083 [=>............................] - ETA: 4s - loss: 0.0395 - accuracy:  111/1083 [==>...........................] - ETA: 4s - loss: 0.0384 - accuracy:  120/1083 [==>...........................] - ETA: 4s - loss: 0.0378 - accuracy:  130/1083 [==>...........................] - ETA: 4s - loss: 0.0384 - accuracy:  142/1083 [==>...........................] - ETA: 4s - loss: 0.0385 - accuracy:  152/1083 [===>..........................] - ETA: 4s - loss: 0.0389 - accuracy:  162/1083 [===>..........................] - ETA: 4s - loss: 0.0392 - accuracy:  172/1083 [===>..........................] - ETA: 4s - loss: 0.0395 - accuracy:  183/1083 [====>.........................] - ETA: 4s - loss: 0.0410 - accuracy:  191/1083 [====>.........................] - ETA: 4s - loss: 0.0414 - accuracy:  199/1083 [====>.........................] - ETA: 4s - loss: 0.0413 - accuracy:  208/1083 [====>.........................] - ETA: 4s - loss: 0.0407 - accuracy:  219/1083 [=====>........................] - ETA: 4s - loss: 0.0413 - accuracy:  230/1083 [=====>........................] - ETA: 4s - loss: 0.0417 - accuracy:  240/1083 [=====>........................] - ETA: 4s - loss: 0.0419 - accuracy:  249/1083 [=====>........................] - ETA: 4s - loss: 0.0428 - accuracy:  259/1083 [======>.......................] - ETA: 4s - loss: 0.0428 - accuracy:  269/1083 [======>.......................] - ETA: 4s - loss: 0.0432 - accuracy:  279/1083 [======>.......................] - ETA: 3s - loss: 0.0433 - accuracy:  289/1083 [=======>......................] - ETA: 3s - loss: 0.0436 - accuracy:  299/1083 [=======>......................] - ETA: 3s - loss: 0.0438 - accuracy:  308/1083 [=======>......................] - ETA: 3s - loss: 0.0435 - accuracy:  315/1083 [=======>......................] - ETA: 3s - loss: 0.0436 - accuracy:  326/1083 [========>.....................] - ETA: 3s - loss: 0.0432 - accuracy:  339/1083 [========>.....................] - ETA: 3s - loss: 0.0427 - accuracy:  351/1083 [========>.....................] - ETA: 3s - loss: 0.0425 - accuracy:  363/1083 [=========>....................] - ETA: 3s - loss: 0.0429 - accuracy:  376/1083 [=========>....................] - ETA: 3s - loss: 0.0430 - accuracy:  388/1083 [=========>....................] - ETA: 3s - loss: 0.0433 - accuracy:  402/1083 [==========>...................] - ETA: 3s - loss: 0.0435 - accuracy:  417/1083 [==========>...................] - ETA: 3s - loss: 0.0434 - accuracy:  433/1083 [==========>...................] - ETA: 3s - loss: 0.0438 - accuracy:  448/1083 [===========>..................] - ETA: 2s - loss: 0.0445 - accuracy:  464/1083 [===========>..................] - ETA: 2s - loss: 0.0445 - accuracy:  479/1083 [============>.................] - ETA: 2s - loss: 0.0446 - accuracy:  495/1083 [============>.................] - ETA: 2s - loss: 0.0447 - accuracy:  511/1083 [=============>................] - ETA: 2s - loss: 0.0441 - accuracy:  527/1083 [=============>................] - ETA: 2s - loss: 0.0441 - accuracy:  542/1083 [==============>...............] - ETA: 2s - loss: 0.0439 - accuracy:  557/1083 [==============>...............] - ETA: 2s - loss: 0.0438 - accuracy:  572/1083 [==============>...............] - ETA: 2s - loss: 0.0436 - accuracy:  588/1083 [===============>..............] - ETA: 2s - loss: 0.0434 - accuracy:  603/1083 [===============>..............] - ETA: 2s - loss: 0.0432 - accuracy:  618/1083 [================>.............] - ETA: 2s - loss: 0.0433 - accuracy:  633/1083 [================>.............] - ETA: 1s - loss: 0.0432 - accuracy:  648/1083 [================>.............] - ETA: 1s - loss: 0.0434 - accuracy:  662/1083 [=================>............] - ETA: 1s - loss: 0.0435 - accuracy:  678/1083 [=================>............] - ETA: 1s - loss: 0.0433 - accuracy:  692/1083 [==================>...........] - ETA: 1s - loss: 0.0432 - accuracy:  707/1083 [==================>...........] - ETA: 1s - loss: 0.0429 - accuracy:  722/1083 [===================>..........] - ETA: 1s - loss: 0.0430 - accuracy:  738/1083 [===================>..........] - ETA: 1s - loss: 0.0429 - accuracy:  753/1083 [===================>..........] - ETA: 1s - loss: 0.0430 - accuracy:  768/1083 [====================>.........] - ETA: 1s - loss: 0.0430 - accuracy:  782/1083 [====================>.........] - ETA: 1s - loss: 0.0429 - accuracy:  797/1083 [=====================>........] - ETA: 1s - loss: 0.0428 - accuracy:  812/1083 [=====================>........] - ETA: 1s - loss: 0.0426 - accuracy:  827/1083 [=====================>........] - ETA: 1s - loss: 0.0427 - accuracy:  840/1083 [======================>.......] - ETA: 1s - loss: 0.0425 - accuracy:  856/1083 [======================>.......] - ETA: 0s - loss: 0.0423 - accuracy:  871/1083 [=======================>......] - ETA: 0s - loss: 0.0425 - accuracy:  886/1083 [=======================>......] - ETA: 0s - loss: 0.0425 - accuracy:  901/1083 [=======================>......] - ETA: 0s - loss: 0.0423 - accuracy:  917/1083 [========================>.....] - ETA: 0s - loss: 0.0422 - accuracy:  932/1083 [========================>.....] - ETA: 0s - loss: 0.0423 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.0422 - accuracy:  963/1083 [=========================>....] - ETA: 0s - loss: 0.0423 - accuracy:  979/1083 [==========================>...] - ETA: 0s - loss: 0.0423 - accuracy:  994/1083 [==========================>...] - ETA: 0s - loss: 0.0424 - accuracy: 1009/1083 [==========================>...] - ETA: 0s - loss: 0.0422 - accuracy: 1024/1083 [===========================>..] - ETA: 0s - loss: 0.0421 - accuracy: 1034/1083 [===========================>..] - ETA: 0s - loss: 0.0421 - accuracy: 1045/1083 [===========================>..] - ETA: 0s - loss: 0.0419 - accuracy: 1058/1083 [============================>.] - ETA: 0s - loss: 0.0419 - accuracy: 1071/1083 [============================>.] - ETA: 0s - loss: 0.0418 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0418 - accuracy: 0.9789
Epoch 6/20
   1/1083 [..............................] - ETA: 4s - loss: 0.0699 - accuracy:   14/1083 [..............................] - ETA: 4s - loss: 0.0301 - accuracy:   27/1083 [..............................] - ETA: 4s - loss: 0.0335 - accuracy:   40/1083 [>.............................] - ETA: 4s - loss: 0.0353 - accuracy:   53/1083 [>.............................] - ETA: 4s - loss: 0.0389 - accuracy:   66/1083 [>.............................] - ETA: 4s - loss: 0.0374 - accuracy:   79/1083 [=>............................] - ETA: 3s - loss: 0.0371 - accuracy:   92/1083 [=>............................] - ETA: 3s - loss: 0.0373 - accuracy:  106/1083 [=>............................] - ETA: 3s - loss: 0.0378 - accuracy:  119/1083 [==>...........................] - ETA: 3s - loss: 0.0365 - accuracy:  133/1083 [==>...........................] - ETA: 3s - loss: 0.0367 - accuracy:  147/1083 [===>..........................] - ETA: 3s - loss: 0.0357 - accuracy:  158/1083 [===>..........................] - ETA: 3s - loss: 0.0366 - accuracy:  172/1083 [===>..........................] - ETA: 3s - loss: 0.0365 - accuracy:  188/1083 [====>.........................] - ETA: 3s - loss: 0.0367 - accuracy:  203/1083 [====>.........................] - ETA: 3s - loss: 0.0367 - accuracy:  219/1083 [=====>........................] - ETA: 3s - loss: 0.0365 - accuracy:  234/1083 [=====>........................] - ETA: 3s - loss: 0.0367 - accuracy:  250/1083 [=====>........................] - ETA: 3s - loss: 0.0368 - accuracy:  264/1083 [======>.......................] - ETA: 3s - loss: 0.0365 - accuracy:  280/1083 [======>.......................] - ETA: 2s - loss: 0.0362 - accuracy:  295/1083 [=======>......................] - ETA: 2s - loss: 0.0362 - accuracy:  310/1083 [=======>......................] - ETA: 2s - loss: 0.0367 - accuracy:  325/1083 [========>.....................] - ETA: 2s - loss: 0.0370 - accuracy:  341/1083 [========>.....................] - ETA: 2s - loss: 0.0369 - accuracy:  356/1083 [========>.....................] - ETA: 2s - loss: 0.0372 - accuracy:  372/1083 [=========>....................] - ETA: 2s - loss: 0.0370 - accuracy:  387/1083 [=========>....................] - ETA: 2s - loss: 0.0368 - accuracy:  402/1083 [==========>...................] - ETA: 2s - loss: 0.0369 - accuracy:  417/1083 [==========>...................] - ETA: 2s - loss: 0.0367 - accuracy:  433/1083 [==========>...................] - ETA: 2s - loss: 0.0367 - accuracy:  448/1083 [===========>..................] - ETA: 2s - loss: 0.0367 - accuracy:  463/1083 [===========>..................] - ETA: 2s - loss: 0.0370 - accuracy:  478/1083 [============>.................] - ETA: 2s - loss: 0.0365 - accuracy:  493/1083 [============>.................] - ETA: 2s - loss: 0.0363 - accuracy:  508/1083 [=============>................] - ETA: 2s - loss: 0.0360 - accuracy:  524/1083 [=============>................] - ETA: 1s - loss: 0.0360 - accuracy:  540/1083 [=============>................] - ETA: 1s - loss: 0.0356 - accuracy:  555/1083 [==============>...............] - ETA: 1s - loss: 0.0357 - accuracy:  570/1083 [==============>...............] - ETA: 1s - loss: 0.0353 - accuracy:  585/1083 [===============>..............] - ETA: 1s - loss: 0.0352 - accuracy:  598/1083 [===============>..............] - ETA: 1s - loss: 0.0352 - accuracy:  613/1083 [===============>..............] - ETA: 1s - loss: 0.0352 - accuracy:  626/1083 [================>.............] - ETA: 1s - loss: 0.0354 - accuracy:  642/1083 [================>.............] - ETA: 1s - loss: 0.0357 - accuracy:  658/1083 [=================>............] - ETA: 1s - loss: 0.0356 - accuracy:  674/1083 [=================>............] - ETA: 1s - loss: 0.0358 - accuracy:  689/1083 [==================>...........] - ETA: 1s - loss: 0.0357 - accuracy:  705/1083 [==================>...........] - ETA: 1s - loss: 0.0355 - accuracy:  720/1083 [==================>...........] - ETA: 1s - loss: 0.0358 - accuracy:  736/1083 [===================>..........] - ETA: 1s - loss: 0.0362 - accuracy:  748/1083 [===================>..........] - ETA: 1s - loss: 0.0365 - accuracy:  763/1083 [====================>.........] - ETA: 1s - loss: 0.0366 - accuracy:  778/1083 [====================>.........] - ETA: 1s - loss: 0.0366 - accuracy:  794/1083 [====================>.........] - ETA: 1s - loss: 0.0365 - accuracy:  810/1083 [=====================>........] - ETA: 0s - loss: 0.0364 - accuracy:  826/1083 [=====================>........] - ETA: 0s - loss: 0.0362 - accuracy:  841/1083 [======================>.......] - ETA: 0s - loss: 0.0362 - accuracy:  857/1083 [======================>.......] - ETA: 0s - loss: 0.0361 - accuracy:  873/1083 [=======================>......] - ETA: 0s - loss: 0.0360 - accuracy:  888/1083 [=======================>......] - ETA: 0s - loss: 0.0359 - accuracy:  901/1083 [=======================>......] - ETA: 0s - loss: 0.0358 - accuracy:  917/1083 [========================>.....] - ETA: 0s - loss: 0.0356 - accuracy:  932/1083 [========================>.....] - ETA: 0s - loss: 0.0356 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.0354 - accuracy:  963/1083 [=========================>....] - ETA: 0s - loss: 0.0353 - accuracy:  979/1083 [==========================>...] - ETA: 0s - loss: 0.0353 - accuracy:  994/1083 [==========================>...] - ETA: 0s - loss: 0.0352 - accuracy: 1010/1083 [==========================>...] - ETA: 0s - loss: 0.0351 - accuracy: 1025/1083 [===========================>..] - ETA: 0s - loss: 0.0350 - accuracy: 1041/1083 [===========================>..] - ETA: 0s - loss: 0.0349 - accuracy: 1055/1083 [============================>.] - ETA: 0s - loss: 0.0348 - accuracy: 1071/1083 [============================>.] - ETA: 0s - loss: 0.0346 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0345 - accuracy: 0.9821
Epoch 7/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0441 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.0328 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0287 - accuracy:   49/1083 [>.............................] - ETA: 3s - loss: 0.0303 - accuracy:   64/1083 [>.............................] - ETA: 3s - loss: 0.0289 - accuracy:   80/1083 [=>............................] - ETA: 3s - loss: 0.0271 - accuracy:   96/1083 [=>............................] - ETA: 3s - loss: 0.0263 - accuracy:  111/1083 [==>...........................] - ETA: 3s - loss: 0.0255 - accuracy:  126/1083 [==>...........................] - ETA: 3s - loss: 0.0263 - accuracy:  142/1083 [==>...........................] - ETA: 3s - loss: 0.0270 - accuracy:  157/1083 [===>..........................] - ETA: 3s - loss: 0.0270 - accuracy:  173/1083 [===>..........................] - ETA: 3s - loss: 0.0274 - accuracy:  189/1083 [====>.........................] - ETA: 2s - loss: 0.0282 - accuracy:  205/1083 [====>.........................] - ETA: 2s - loss: 0.0279 - accuracy:  221/1083 [=====>........................] - ETA: 2s - loss: 0.0280 - accuracy:  237/1083 [=====>........................] - ETA: 2s - loss: 0.0278 - accuracy:  250/1083 [=====>........................] - ETA: 2s - loss: 0.0280 - accuracy:  264/1083 [======>.......................] - ETA: 2s - loss: 0.0282 - accuracy:  279/1083 [======>.......................] - ETA: 2s - loss: 0.0280 - accuracy:  293/1083 [=======>......................] - ETA: 2s - loss: 0.0277 - accuracy:  308/1083 [=======>......................] - ETA: 2s - loss: 0.0275 - accuracy:  323/1083 [=======>......................] - ETA: 2s - loss: 0.0280 - accuracy:  339/1083 [========>.....................] - ETA: 2s - loss: 0.0278 - accuracy:  354/1083 [========>.....................] - ETA: 2s - loss: 0.0275 - accuracy:  369/1083 [=========>....................] - ETA: 2s - loss: 0.0280 - accuracy:  385/1083 [=========>....................] - ETA: 2s - loss: 0.0279 - accuracy:  400/1083 [==========>...................] - ETA: 2s - loss: 0.0278 - accuracy:  416/1083 [==========>...................] - ETA: 2s - loss: 0.0279 - accuracy:  432/1083 [==========>...................] - ETA: 2s - loss: 0.0282 - accuracy:  448/1083 [===========>..................] - ETA: 2s - loss: 0.0283 - accuracy:  464/1083 [===========>..................] - ETA: 2s - loss: 0.0282 - accuracy:  480/1083 [============>.................] - ETA: 2s - loss: 0.0281 - accuracy:  495/1083 [============>.................] - ETA: 1s - loss: 0.0280 - accuracy:  511/1083 [=============>................] - ETA: 1s - loss: 0.0282 - accuracy:  527/1083 [=============>................] - ETA: 1s - loss: 0.0281 - accuracy:  543/1083 [==============>...............] - ETA: 1s - loss: 0.0280 - accuracy:  558/1083 [==============>...............] - ETA: 1s - loss: 0.0280 - accuracy:  574/1083 [==============>...............] - ETA: 1s - loss: 0.0281 - accuracy:  590/1083 [===============>..............] - ETA: 1s - loss: 0.0280 - accuracy:  606/1083 [===============>..............] - ETA: 1s - loss: 0.0280 - accuracy:  622/1083 [================>.............] - ETA: 1s - loss: 0.0280 - accuracy:  638/1083 [================>.............] - ETA: 1s - loss: 0.0281 - accuracy:  653/1083 [=================>............] - ETA: 1s - loss: 0.0282 - accuracy:  669/1083 [=================>............] - ETA: 1s - loss: 0.0282 - accuracy:  685/1083 [=================>............] - ETA: 1s - loss: 0.0284 - accuracy:  700/1083 [==================>...........] - ETA: 1s - loss: 0.0284 - accuracy:  714/1083 [==================>...........] - ETA: 1s - loss: 0.0284 - accuracy:  730/1083 [===================>..........] - ETA: 1s - loss: 0.0283 - accuracy:  745/1083 [===================>..........] - ETA: 1s - loss: 0.0284 - accuracy:  761/1083 [====================>.........] - ETA: 1s - loss: 0.0284 - accuracy:  777/1083 [====================>.........] - ETA: 1s - loss: 0.0285 - accuracy:  792/1083 [====================>.........] - ETA: 0s - loss: 0.0283 - accuracy:  807/1083 [=====================>........] - ETA: 0s - loss: 0.0284 - accuracy:  823/1083 [=====================>........] - ETA: 0s - loss: 0.0285 - accuracy:  839/1083 [======================>.......] - ETA: 0s - loss: 0.0284 - accuracy:  848/1083 [======================>.......] - ETA: 0s - loss: 0.0285 - accuracy:  861/1083 [======================>.......] - ETA: 0s - loss: 0.0285 - accuracy:  876/1083 [=======================>......] - ETA: 0s - loss: 0.0285 - accuracy:  890/1083 [=======================>......] - ETA: 0s - loss: 0.0285 - accuracy:  905/1083 [========================>.....] - ETA: 0s - loss: 0.0285 - accuracy:  918/1083 [========================>.....] - ETA: 0s - loss: 0.0284 - accuracy:  933/1083 [========================>.....] - ETA: 0s - loss: 0.0283 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.0283 - accuracy:  963/1083 [=========================>....] - ETA: 0s - loss: 0.0282 - accuracy:  976/1083 [==========================>...] - ETA: 0s - loss: 0.0282 - accuracy:  991/1083 [==========================>...] - ETA: 0s - loss: 0.0281 - accuracy: 1007/1083 [==========================>...] - ETA: 0s - loss: 0.0282 - accuracy: 1023/1083 [===========================>..] - ETA: 0s - loss: 0.0281 - accuracy: 1031/1083 [===========================>..] - ETA: 0s - loss: 0.0281 - accuracy: 1046/1083 [===========================>..] - ETA: 0s - loss: 0.0281 - accuracy: 1062/1083 [============================>.] - ETA: 0s - loss: 0.0281 - accuracy: 1079/1083 [============================>.] - ETA: 0s - loss: 0.0280 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0279 - accuracy: 0.9862
Epoch 8/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0036 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.0283 - accuracy:   31/1083 [..............................] - ETA: 3s - loss: 0.0266 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0285 - accuracy:   63/1083 [>.............................] - ETA: 3s - loss: 0.0301 - accuracy:   80/1083 [=>............................] - ETA: 3s - loss: 0.0290 - accuracy:   96/1083 [=>............................] - ETA: 3s - loss: 0.0284 - accuracy:  111/1083 [==>...........................] - ETA: 3s - loss: 0.0282 - accuracy:  127/1083 [==>...........................] - ETA: 3s - loss: 0.0280 - accuracy:  143/1083 [==>...........................] - ETA: 3s - loss: 0.0277 - accuracy:  158/1083 [===>..........................] - ETA: 3s - loss: 0.0285 - accuracy:  175/1083 [===>..........................] - ETA: 2s - loss: 0.0301 - accuracy:  190/1083 [====>.........................] - ETA: 2s - loss: 0.0298 - accuracy:  204/1083 [====>.........................] - ETA: 2s - loss: 0.0302 - accuracy:  218/1083 [=====>........................] - ETA: 2s - loss: 0.0296 - accuracy:  233/1083 [=====>........................] - ETA: 2s - loss: 0.0296 - accuracy:  248/1083 [=====>........................] - ETA: 2s - loss: 0.0298 - accuracy:  264/1083 [======>.......................] - ETA: 2s - loss: 0.0293 - accuracy:  279/1083 [======>.......................] - ETA: 2s - loss: 0.0291 - accuracy:  295/1083 [=======>......................] - ETA: 2s - loss: 0.0287 - accuracy:  311/1083 [=======>......................] - ETA: 2s - loss: 0.0283 - accuracy:  327/1083 [========>.....................] - ETA: 2s - loss: 0.0281 - accuracy:  341/1083 [========>.....................] - ETA: 2s - loss: 0.0278 - accuracy:  354/1083 [========>.....................] - ETA: 2s - loss: 0.0275 - accuracy:  369/1083 [=========>....................] - ETA: 2s - loss: 0.0273 - accuracy:  385/1083 [=========>....................] - ETA: 2s - loss: 0.0269 - accuracy:  400/1083 [==========>...................] - ETA: 2s - loss: 0.0270 - accuracy:  417/1083 [==========>...................] - ETA: 2s - loss: 0.0268 - accuracy:  433/1083 [==========>...................] - ETA: 2s - loss: 0.0268 - accuracy:  449/1083 [===========>..................] - ETA: 2s - loss: 0.0269 - accuracy:  464/1083 [===========>..................] - ETA: 2s - loss: 0.0266 - accuracy:  480/1083 [============>.................] - ETA: 2s - loss: 0.0264 - accuracy:  495/1083 [============>.................] - ETA: 1s - loss: 0.0264 - accuracy:  510/1083 [=============>................] - ETA: 1s - loss: 0.0262 - accuracy:  524/1083 [=============>................] - ETA: 1s - loss: 0.0262 - accuracy:  540/1083 [=============>................] - ETA: 1s - loss: 0.0260 - accuracy:  556/1083 [==============>...............] - ETA: 1s - loss: 0.0258 - accuracy:  570/1083 [==============>...............] - ETA: 1s - loss: 0.0257 - accuracy:  584/1083 [===============>..............] - ETA: 1s - loss: 0.0255 - accuracy:  599/1083 [===============>..............] - ETA: 1s - loss: 0.0254 - accuracy:  615/1083 [================>.............] - ETA: 1s - loss: 0.0255 - accuracy:  631/1083 [================>.............] - ETA: 1s - loss: 0.0256 - accuracy:  647/1083 [================>.............] - ETA: 1s - loss: 0.0255 - accuracy:  663/1083 [=================>............] - ETA: 1s - loss: 0.0254 - accuracy:  678/1083 [=================>............] - ETA: 1s - loss: 0.0253 - accuracy:  694/1083 [==================>...........] - ETA: 1s - loss: 0.0252 - accuracy:  709/1083 [==================>...........] - ETA: 1s - loss: 0.0249 - accuracy:  724/1083 [===================>..........] - ETA: 1s - loss: 0.0249 - accuracy:  739/1083 [===================>..........] - ETA: 1s - loss: 0.0249 - accuracy:  756/1083 [===================>..........] - ETA: 1s - loss: 0.0249 - accuracy:  771/1083 [====================>.........] - ETA: 1s - loss: 0.0254 - accuracy:  787/1083 [====================>.........] - ETA: 0s - loss: 0.0254 - accuracy:  802/1083 [=====================>........] - ETA: 0s - loss: 0.0253 - accuracy:  817/1083 [=====================>........] - ETA: 0s - loss: 0.0253 - accuracy:  833/1083 [======================>.......] - ETA: 0s - loss: 0.0252 - accuracy:  848/1083 [======================>.......] - ETA: 0s - loss: 0.0252 - accuracy:  862/1083 [======================>.......] - ETA: 0s - loss: 0.0252 - accuracy:  878/1083 [=======================>......] - ETA: 0s - loss: 0.0252 - accuracy:  894/1083 [=======================>......] - ETA: 0s - loss: 0.0250 - accuracy:  910/1083 [========================>.....] - ETA: 0s - loss: 0.0250 - accuracy:  926/1083 [========================>.....] - ETA: 0s - loss: 0.0249 - accuracy:  941/1083 [=========================>....] - ETA: 0s - loss: 0.0248 - accuracy:  954/1083 [=========================>....] - ETA: 0s - loss: 0.0248 - accuracy:  969/1083 [=========================>....] - ETA: 0s - loss: 0.0246 - accuracy:  986/1083 [==========================>...] - ETA: 0s - loss: 0.0245 - accuracy: 1002/1083 [==========================>...] - ETA: 0s - loss: 0.0244 - accuracy: 1017/1083 [===========================>..] - ETA: 0s - loss: 0.0243 - accuracy: 1033/1083 [===========================>..] - ETA: 0s - loss: 0.0241 - accuracy: 1046/1083 [===========================>..] - ETA: 0s - loss: 0.0241 - accuracy: 1060/1083 [============================>.] - ETA: 0s - loss: 0.0242 - accuracy: 1074/1083 [============================>.] - ETA: 0s - loss: 0.0240 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0241 - accuracy: 0.9885
Epoch 9/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0073 - accuracy:   17/1083 [..............................] - ETA: 3s - loss: 0.0169 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0165 - accuracy:   48/1083 [>.............................] - ETA: 3s - loss: 0.0188 - accuracy:   63/1083 [>.............................] - ETA: 3s - loss: 0.0180 - accuracy:   79/1083 [=>............................] - ETA: 3s - loss: 0.0181 - accuracy:   95/1083 [=>............................] - ETA: 3s - loss: 0.0187 - accuracy:  111/1083 [==>...........................] - ETA: 3s - loss: 0.0186 - accuracy:  127/1083 [==>...........................] - ETA: 3s - loss: 0.0180 - accuracy:  143/1083 [==>...........................] - ETA: 3s - loss: 0.0185 - accuracy:  156/1083 [===>..........................] - ETA: 3s - loss: 0.0181 - accuracy:  171/1083 [===>..........................] - ETA: 3s - loss: 0.0190 - accuracy:  186/1083 [====>.........................] - ETA: 3s - loss: 0.0192 - accuracy:  202/1083 [====>.........................] - ETA: 2s - loss: 0.0191 - accuracy:  217/1083 [=====>........................] - ETA: 2s - loss: 0.0193 - accuracy:  233/1083 [=====>........................] - ETA: 2s - loss: 0.0201 - accuracy:  249/1083 [=====>........................] - ETA: 2s - loss: 0.0201 - accuracy:  265/1083 [======>.......................] - ETA: 2s - loss: 0.0203 - accuracy:  281/1083 [======>.......................] - ETA: 2s - loss: 0.0201 - accuracy:  297/1083 [=======>......................] - ETA: 2s - loss: 0.0203 - accuracy:  312/1083 [=======>......................] - ETA: 2s - loss: 0.0205 - accuracy:  328/1083 [========>.....................] - ETA: 2s - loss: 0.0205 - accuracy:  343/1083 [========>.....................] - ETA: 2s - loss: 0.0207 - accuracy:  358/1083 [========>.....................] - ETA: 2s - loss: 0.0212 - accuracy:  374/1083 [=========>....................] - ETA: 2s - loss: 0.0210 - accuracy:  390/1083 [=========>....................] - ETA: 2s - loss: 0.0213 - accuracy:  404/1083 [==========>...................] - ETA: 2s - loss: 0.0214 - accuracy:  420/1083 [==========>...................] - ETA: 2s - loss: 0.0212 - accuracy:  436/1083 [===========>..................] - ETA: 2s - loss: 0.0210 - accuracy:  450/1083 [===========>..................] - ETA: 2s - loss: 0.0209 - accuracy:  464/1083 [===========>..................] - ETA: 2s - loss: 0.0210 - accuracy:  480/1083 [============>.................] - ETA: 2s - loss: 0.0211 - accuracy:  494/1083 [============>.................] - ETA: 1s - loss: 0.0210 - accuracy:  510/1083 [=============>................] - ETA: 1s - loss: 0.0212 - accuracy:  526/1083 [=============>................] - ETA: 1s - loss: 0.0212 - accuracy:  541/1083 [=============>................] - ETA: 1s - loss: 0.0213 - accuracy:  556/1083 [==============>...............] - ETA: 1s - loss: 0.0213 - accuracy:  572/1083 [==============>...............] - ETA: 1s - loss: 0.0212 - accuracy:  586/1083 [===============>..............] - ETA: 1s - loss: 0.0214 - accuracy:  601/1083 [===============>..............] - ETA: 1s - loss: 0.0213 - accuracy:  617/1083 [================>.............] - ETA: 1s - loss: 0.0213 - accuracy:  633/1083 [================>.............] - ETA: 1s - loss: 0.0214 - accuracy:  648/1083 [================>.............] - ETA: 1s - loss: 0.0216 - accuracy:  663/1083 [=================>............] - ETA: 1s - loss: 0.0215 - accuracy:  679/1083 [=================>............] - ETA: 1s - loss: 0.0213 - accuracy:  695/1083 [==================>...........] - ETA: 1s - loss: 0.0214 - accuracy:  709/1083 [==================>...........] - ETA: 1s - loss: 0.0214 - accuracy:  725/1083 [===================>..........] - ETA: 1s - loss: 0.0212 - accuracy:  740/1083 [===================>..........] - ETA: 1s - loss: 0.0211 - accuracy:  756/1083 [===================>..........] - ETA: 1s - loss: 0.0210 - accuracy:  772/1083 [====================>.........] - ETA: 1s - loss: 0.0211 - accuracy:  788/1083 [====================>.........] - ETA: 0s - loss: 0.0211 - accuracy:  803/1083 [=====================>........] - ETA: 0s - loss: 0.0211 - accuracy:  819/1083 [=====================>........] - ETA: 0s - loss: 0.0210 - accuracy:  834/1083 [======================>.......] - ETA: 0s - loss: 0.0211 - accuracy:  850/1083 [======================>.......] - ETA: 0s - loss: 0.0210 - accuracy:  865/1083 [======================>.......] - ETA: 0s - loss: 0.0209 - accuracy:  881/1083 [=======================>......] - ETA: 0s - loss: 0.0209 - accuracy:  896/1083 [=======================>......] - ETA: 0s - loss: 0.0209 - accuracy:  911/1083 [========================>.....] - ETA: 0s - loss: 0.0207 - accuracy:  926/1083 [========================>.....] - ETA: 0s - loss: 0.0206 - accuracy:  941/1083 [=========================>....] - ETA: 0s - loss: 0.0206 - accuracy:  956/1083 [=========================>....] - ETA: 0s - loss: 0.0206 - accuracy:  972/1083 [=========================>....] - ETA: 0s - loss: 0.0205 - accuracy:  987/1083 [==========================>...] - ETA: 0s - loss: 0.0205 - accuracy: 1003/1083 [==========================>...] - ETA: 0s - loss: 0.0205 - accuracy: 1018/1083 [===========================>..] - ETA: 0s - loss: 0.0206 - accuracy: 1034/1083 [===========================>..] - ETA: 0s - loss: 0.0205 - accuracy: 1047/1083 [============================>.] - ETA: 0s - loss: 0.0204 - accuracy: 1062/1083 [============================>.] - ETA: 0s - loss: 0.0205 - accuracy: 1078/1083 [============================>.] - ETA: 0s - loss: 0.0205 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0204 - accuracy: 0.9897
Epoch 10/20
   1/1083 [..............................] - ETA: 4s - loss: 0.0178 - accuracy:   18/1083 [..............................] - ETA: 3s - loss: 0.0250 - accuracy:   34/1083 [..............................] - ETA: 3s - loss: 0.0211 - accuracy:   50/1083 [>.............................] - ETA: 3s - loss: 0.0180 - accuracy:   65/1083 [>.............................] - ETA: 3s - loss: 0.0188 - accuracy:   82/1083 [=>............................] - ETA: 3s - loss: 0.0173 - accuracy:   97/1083 [=>............................] - ETA: 3s - loss: 0.0177 - accuracy:  112/1083 [==>...........................] - ETA: 3s - loss: 0.0177 - accuracy:  127/1083 [==>...........................] - ETA: 3s - loss: 0.0185 - accuracy:  142/1083 [==>...........................] - ETA: 3s - loss: 0.0189 - accuracy:  157/1083 [===>..........................] - ETA: 3s - loss: 0.0190 - accuracy:  173/1083 [===>..........................] - ETA: 2s - loss: 0.0190 - accuracy:  189/1083 [====>.........................] - ETA: 2s - loss: 0.0186 - accuracy:  205/1083 [====>.........................] - ETA: 2s - loss: 0.0180 - accuracy:  221/1083 [=====>........................] - ETA: 2s - loss: 0.0178 - accuracy:  237/1083 [=====>........................] - ETA: 2s - loss: 0.0172 - accuracy:  253/1083 [======>.......................] - ETA: 2s - loss: 0.0175 - accuracy:  269/1083 [======>.......................] - ETA: 2s - loss: 0.0171 - accuracy:  284/1083 [======>.......................] - ETA: 2s - loss: 0.0172 - accuracy:  300/1083 [=======>......................] - ETA: 2s - loss: 0.0178 - accuracy:  316/1083 [=======>......................] - ETA: 2s - loss: 0.0180 - accuracy:  332/1083 [========>.....................] - ETA: 2s - loss: 0.0181 - accuracy:  347/1083 [========>.....................] - ETA: 2s - loss: 0.0178 - accuracy:  363/1083 [=========>....................] - ETA: 2s - loss: 0.0176 - accuracy:  378/1083 [=========>....................] - ETA: 2s - loss: 0.0180 - accuracy:  394/1083 [=========>....................] - ETA: 2s - loss: 0.0180 - accuracy:  410/1083 [==========>...................] - ETA: 2s - loss: 0.0177 - accuracy:  425/1083 [==========>...................] - ETA: 2s - loss: 0.0178 - accuracy:  440/1083 [===========>..................] - ETA: 2s - loss: 0.0175 - accuracy:  456/1083 [===========>..................] - ETA: 2s - loss: 0.0175 - accuracy:  472/1083 [============>.................] - ETA: 2s - loss: 0.0173 - accuracy:  487/1083 [============>.................] - ETA: 1s - loss: 0.0174 - accuracy:  502/1083 [============>.................] - ETA: 1s - loss: 0.0172 - accuracy:  518/1083 [=============>................] - ETA: 1s - loss: 0.0170 - accuracy:  534/1083 [=============>................] - ETA: 1s - loss: 0.0171 - accuracy:  550/1083 [==============>...............] - ETA: 1s - loss: 0.0174 - accuracy:  566/1083 [==============>...............] - ETA: 1s - loss: 0.0175 - accuracy:  581/1083 [===============>..............] - ETA: 1s - loss: 0.0175 - accuracy:  594/1083 [===============>..............] - ETA: 1s - loss: 0.0175 - accuracy:  610/1083 [===============>..............] - ETA: 1s - loss: 0.0176 - accuracy:  626/1083 [================>.............] - ETA: 1s - loss: 0.0176 - accuracy:  643/1083 [================>.............] - ETA: 1s - loss: 0.0176 - accuracy:  659/1083 [=================>............] - ETA: 1s - loss: 0.0175 - accuracy:  675/1083 [=================>............] - ETA: 1s - loss: 0.0173 - accuracy:  691/1083 [==================>...........] - ETA: 1s - loss: 0.0174 - accuracy:  707/1083 [==================>...........] - ETA: 1s - loss: 0.0177 - accuracy:  723/1083 [===================>..........] - ETA: 1s - loss: 0.0176 - accuracy:  739/1083 [===================>..........] - ETA: 1s - loss: 0.0178 - accuracy:  754/1083 [===================>..........] - ETA: 1s - loss: 0.0177 - accuracy:  769/1083 [====================>.........] - ETA: 1s - loss: 0.0178 - accuracy:  784/1083 [====================>.........] - ETA: 0s - loss: 0.0177 - accuracy:  800/1083 [=====================>........] - ETA: 0s - loss: 0.0178 - accuracy:  816/1083 [=====================>........] - ETA: 0s - loss: 0.0177 - accuracy:  831/1083 [======================>.......] - ETA: 0s - loss: 0.0177 - accuracy:  846/1083 [======================>.......] - ETA: 0s - loss: 0.0177 - accuracy:  862/1083 [======================>.......] - ETA: 0s - loss: 0.0177 - accuracy:  876/1083 [=======================>......] - ETA: 0s - loss: 0.0177 - accuracy:  892/1083 [=======================>......] - ETA: 0s - loss: 0.0178 - accuracy:  907/1083 [========================>.....] - ETA: 0s - loss: 0.0177 - accuracy:  922/1083 [========================>.....] - ETA: 0s - loss: 0.0177 - accuracy:  937/1083 [========================>.....] - ETA: 0s - loss: 0.0178 - accuracy:  952/1083 [=========================>....] - ETA: 0s - loss: 0.0178 - accuracy:  968/1083 [=========================>....] - ETA: 0s - loss: 0.0177 - accuracy:  984/1083 [==========================>...] - ETA: 0s - loss: 0.0176 - accuracy:  994/1083 [==========================>...] - ETA: 0s - loss: 0.0176 - accuracy: 1004/1083 [==========================>...] - ETA: 0s - loss: 0.0175 - accuracy: 1016/1083 [===========================>..] - ETA: 0s - loss: 0.0175 - accuracy: 1031/1083 [===========================>..] - ETA: 0s - loss: 0.0174 - accuracy: 1046/1083 [===========================>..] - ETA: 0s - loss: 0.0174 - accuracy: 1062/1083 [============================>.] - ETA: 0s - loss: 0.0173 - accuracy: 1077/1083 [============================>.] - ETA: 0s - loss: 0.0172 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0172 - accuracy: 0.9914
Epoch 11/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0013 - accuracy:   17/1083 [..............................] - ETA: 3s - loss: 0.0195 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0164 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0137 - accuracy:   62/1083 [>.............................] - ETA: 3s - loss: 0.0143 - accuracy:   76/1083 [=>............................] - ETA: 3s - loss: 0.0141 - accuracy:   91/1083 [=>............................] - ETA: 3s - loss: 0.0155 - accuracy:  106/1083 [=>............................] - ETA: 3s - loss: 0.0163 - accuracy:  122/1083 [==>...........................] - ETA: 3s - loss: 0.0161 - accuracy:  138/1083 [==>...........................] - ETA: 3s - loss: 0.0161 - accuracy:  154/1083 [===>..........................] - ETA: 3s - loss: 0.0156 - accuracy:  170/1083 [===>..........................] - ETA: 3s - loss: 0.0148 - accuracy:  186/1083 [====>.........................] - ETA: 3s - loss: 0.0145 - accuracy:  202/1083 [====>.........................] - ETA: 2s - loss: 0.0145 - accuracy:  218/1083 [=====>........................] - ETA: 2s - loss: 0.0143 - accuracy:  234/1083 [=====>........................] - ETA: 2s - loss: 0.0148 - accuracy:  249/1083 [=====>........................] - ETA: 2s - loss: 0.0151 - accuracy:  264/1083 [======>.......................] - ETA: 2s - loss: 0.0152 - accuracy:  280/1083 [======>.......................] - ETA: 2s - loss: 0.0149 - accuracy:  296/1083 [=======>......................] - ETA: 2s - loss: 0.0151 - accuracy:  312/1083 [=======>......................] - ETA: 2s - loss: 0.0148 - accuracy:  328/1083 [========>.....................] - ETA: 2s - loss: 0.0148 - accuracy:  341/1083 [========>.....................] - ETA: 2s - loss: 0.0150 - accuracy:  357/1083 [========>.....................] - ETA: 2s - loss: 0.0151 - accuracy:  372/1083 [=========>....................] - ETA: 2s - loss: 0.0153 - accuracy:  387/1083 [=========>....................] - ETA: 2s - loss: 0.0155 - accuracy:  403/1083 [==========>...................] - ETA: 2s - loss: 0.0155 - accuracy:  419/1083 [==========>...................] - ETA: 2s - loss: 0.0154 - accuracy:  435/1083 [===========>..................] - ETA: 2s - loss: 0.0154 - accuracy:  452/1083 [===========>..................] - ETA: 2s - loss: 0.0154 - accuracy:  466/1083 [===========>..................] - ETA: 2s - loss: 0.0153 - accuracy:  482/1083 [============>.................] - ETA: 2s - loss: 0.0155 - accuracy:  497/1083 [============>.................] - ETA: 1s - loss: 0.0155 - accuracy:  512/1083 [=============>................] - ETA: 1s - loss: 0.0155 - accuracy:  525/1083 [=============>................] - ETA: 1s - loss: 0.0154 - accuracy:  540/1083 [=============>................] - ETA: 1s - loss: 0.0154 - accuracy:  553/1083 [==============>...............] - ETA: 1s - loss: 0.0153 - accuracy:  568/1083 [==============>...............] - ETA: 1s - loss: 0.0152 - accuracy:  582/1083 [===============>..............] - ETA: 1s - loss: 0.0151 - accuracy:  597/1083 [===============>..............] - ETA: 1s - loss: 0.0152 - accuracy:  610/1083 [===============>..............] - ETA: 1s - loss: 0.0153 - accuracy:  626/1083 [================>.............] - ETA: 1s - loss: 0.0153 - accuracy:  641/1083 [================>.............] - ETA: 1s - loss: 0.0151 - accuracy:  655/1083 [=================>............] - ETA: 1s - loss: 0.0151 - accuracy:  668/1083 [=================>............] - ETA: 1s - loss: 0.0151 - accuracy:  684/1083 [=================>............] - ETA: 1s - loss: 0.0149 - accuracy:  697/1083 [==================>...........] - ETA: 1s - loss: 0.0150 - accuracy:  712/1083 [==================>...........] - ETA: 1s - loss: 0.0149 - accuracy:  726/1083 [===================>..........] - ETA: 1s - loss: 0.0149 - accuracy:  741/1083 [===================>..........] - ETA: 1s - loss: 0.0148 - accuracy:  755/1083 [===================>..........] - ETA: 1s - loss: 0.0147 - accuracy:  769/1083 [====================>.........] - ETA: 1s - loss: 0.0146 - accuracy:  784/1083 [====================>.........] - ETA: 1s - loss: 0.0145 - accuracy:  795/1083 [=====================>........] - ETA: 0s - loss: 0.0147 - accuracy:  807/1083 [=====================>........] - ETA: 0s - loss: 0.0149 - accuracy:  823/1083 [=====================>........] - ETA: 0s - loss: 0.0150 - accuracy:  835/1083 [======================>.......] - ETA: 0s - loss: 0.0150 - accuracy:  846/1083 [======================>.......] - ETA: 0s - loss: 0.0149 - accuracy:  861/1083 [======================>.......] - ETA: 0s - loss: 0.0150 - accuracy:  876/1083 [=======================>......] - ETA: 0s - loss: 0.0150 - accuracy:  892/1083 [=======================>......] - ETA: 0s - loss: 0.0152 - accuracy:  908/1083 [========================>.....] - ETA: 0s - loss: 0.0152 - accuracy:  922/1083 [========================>.....] - ETA: 0s - loss: 0.0152 - accuracy:  936/1083 [========================>.....] - ETA: 0s - loss: 0.0152 - accuracy:  946/1083 [=========================>....] - ETA: 0s - loss: 0.0151 - accuracy:  960/1083 [=========================>....] - ETA: 0s - loss: 0.0150 - accuracy:  973/1083 [=========================>....] - ETA: 0s - loss: 0.0151 - accuracy:  986/1083 [==========================>...] - ETA: 0s - loss: 0.0151 - accuracy: 1000/1083 [==========================>...] - ETA: 0s - loss: 0.0152 - accuracy: 1016/1083 [===========================>..] - ETA: 0s - loss: 0.0152 - accuracy: 1030/1083 [===========================>..] - ETA: 0s - loss: 0.0151 - accuracy: 1040/1083 [===========================>..] - ETA: 0s - loss: 0.0152 - accuracy: 1050/1083 [============================>.] - ETA: 0s - loss: 0.0151 - accuracy: 1063/1083 [============================>.] - ETA: 0s - loss: 0.0150 - accuracy: 1075/1083 [============================>.] - ETA: 0s - loss: 0.0150 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0150 - accuracy: 0.9924
Epoch 12/20
   1/1083 [..............................] - ETA: 4s - loss: 0.0026 - accuracy:   13/1083 [..............................] - ETA: 4s - loss: 0.0092 - accuracy:   25/1083 [..............................] - ETA: 4s - loss: 0.0106 - accuracy:   37/1083 [>.............................] - ETA: 4s - loss: 0.0107 - accuracy:   50/1083 [>.............................] - ETA: 4s - loss: 0.0122 - accuracy:   63/1083 [>.............................] - ETA: 4s - loss: 0.0125 - accuracy:   76/1083 [=>............................] - ETA: 4s - loss: 0.0127 - accuracy:   87/1083 [=>............................] - ETA: 4s - loss: 0.0120 - accuracy:  100/1083 [=>............................] - ETA: 4s - loss: 0.0126 - accuracy:  113/1083 [==>...........................] - ETA: 4s - loss: 0.0123 - accuracy:  129/1083 [==>...........................] - ETA: 3s - loss: 0.0121 - accuracy:  144/1083 [==>...........................] - ETA: 3s - loss: 0.0124 - accuracy:  159/1083 [===>..........................] - ETA: 3s - loss: 0.0133 - accuracy:  174/1083 [===>..........................] - ETA: 3s - loss: 0.0133 - accuracy:  187/1083 [====>.........................] - ETA: 3s - loss: 0.0132 - accuracy:  201/1083 [====>.........................] - ETA: 3s - loss: 0.0133 - accuracy:  216/1083 [====>.........................] - ETA: 3s - loss: 0.0129 - accuracy:  230/1083 [=====>........................] - ETA: 3s - loss: 0.0127 - accuracy:  243/1083 [=====>........................] - ETA: 3s - loss: 0.0131 - accuracy:  255/1083 [======>.......................] - ETA: 3s - loss: 0.0130 - accuracy:  269/1083 [======>.......................] - ETA: 3s - loss: 0.0130 - accuracy:  282/1083 [======>.......................] - ETA: 3s - loss: 0.0129 - accuracy:  297/1083 [=======>......................] - ETA: 3s - loss: 0.0128 - accuracy:  311/1083 [=======>......................] - ETA: 2s - loss: 0.0126 - accuracy:  320/1083 [=======>......................] - ETA: 2s - loss: 0.0127 - accuracy:  332/1083 [========>.....................] - ETA: 2s - loss: 0.0128 - accuracy:  345/1083 [========>.....................] - ETA: 2s - loss: 0.0126 - accuracy:  356/1083 [========>.....................] - ETA: 2s - loss: 0.0127 - accuracy:  367/1083 [=========>....................] - ETA: 2s - loss: 0.0127 - accuracy:  378/1083 [=========>....................] - ETA: 2s - loss: 0.0128 - accuracy:  390/1083 [=========>....................] - ETA: 2s - loss: 0.0127 - accuracy:  403/1083 [==========>...................] - ETA: 2s - loss: 0.0131 - accuracy:  415/1083 [==========>...................] - ETA: 2s - loss: 0.0131 - accuracy:  428/1083 [==========>...................] - ETA: 2s - loss: 0.0133 - accuracy:  441/1083 [===========>..................] - ETA: 2s - loss: 0.0134 - accuracy:  455/1083 [===========>..................] - ETA: 2s - loss: 0.0134 - accuracy:  468/1083 [===========>..................] - ETA: 2s - loss: 0.0133 - accuracy:  482/1083 [============>.................] - ETA: 2s - loss: 0.0132 - accuracy:  495/1083 [============>.................] - ETA: 2s - loss: 0.0131 - accuracy:  509/1083 [=============>................] - ETA: 2s - loss: 0.0132 - accuracy:  522/1083 [=============>................] - ETA: 2s - loss: 0.0131 - accuracy:  535/1083 [=============>................] - ETA: 2s - loss: 0.0130 - accuracy:  548/1083 [==============>...............] - ETA: 2s - loss: 0.0132 - accuracy:  562/1083 [==============>...............] - ETA: 2s - loss: 0.0132 - accuracy:  575/1083 [==============>...............] - ETA: 2s - loss: 0.0132 - accuracy:  591/1083 [===============>..............] - ETA: 1s - loss: 0.0131 - accuracy:  604/1083 [===============>..............] - ETA: 1s - loss: 0.0132 - accuracy:  620/1083 [================>.............] - ETA: 1s - loss: 0.0132 - accuracy:  636/1083 [================>.............] - ETA: 1s - loss: 0.0130 - accuracy:  652/1083 [=================>............] - ETA: 1s - loss: 0.0129 - accuracy:  667/1083 [=================>............] - ETA: 1s - loss: 0.0130 - accuracy:  683/1083 [=================>............] - ETA: 1s - loss: 0.0131 - accuracy:  698/1083 [==================>...........] - ETA: 1s - loss: 0.0129 - accuracy:  714/1083 [==================>...........] - ETA: 1s - loss: 0.0129 - accuracy:  729/1083 [===================>..........] - ETA: 1s - loss: 0.0130 - accuracy:  744/1083 [===================>..........] - ETA: 1s - loss: 0.0129 - accuracy:  759/1083 [====================>.........] - ETA: 1s - loss: 0.0128 - accuracy:  775/1083 [====================>.........] - ETA: 1s - loss: 0.0127 - accuracy:  790/1083 [====================>.........] - ETA: 1s - loss: 0.0128 - accuracy:  806/1083 [=====================>........] - ETA: 1s - loss: 0.0128 - accuracy:  821/1083 [=====================>........] - ETA: 0s - loss: 0.0128 - accuracy:  837/1083 [======================>.......] - ETA: 0s - loss: 0.0127 - accuracy:  852/1083 [======================>.......] - ETA: 0s - loss: 0.0127 - accuracy:  868/1083 [=======================>......] - ETA: 0s - loss: 0.0126 - accuracy:  884/1083 [=======================>......] - ETA: 0s - loss: 0.0125 - accuracy:  899/1083 [=======================>......] - ETA: 0s - loss: 0.0124 - accuracy:  914/1083 [========================>.....] - ETA: 0s - loss: 0.0124 - accuracy:  929/1083 [========================>.....] - ETA: 0s - loss: 0.0124 - accuracy:  943/1083 [=========================>....] - ETA: 0s - loss: 0.0124 - accuracy:  959/1083 [=========================>....] - ETA: 0s - loss: 0.0125 - accuracy:  973/1083 [=========================>....] - ETA: 0s - loss: 0.0125 - accuracy:  988/1083 [==========================>...] - ETA: 0s - loss: 0.0124 - accuracy: 1004/1083 [==========================>...] - ETA: 0s - loss: 0.0126 - accuracy: 1020/1083 [===========================>..] - ETA: 0s - loss: 0.0126 - accuracy: 1034/1083 [===========================>..] - ETA: 0s - loss: 0.0125 - accuracy: 1049/1083 [============================>.] - ETA: 0s - loss: 0.0125 - accuracy: 1065/1083 [============================>.] - ETA: 0s - loss: 0.0124 - accuracy: 1081/1083 [============================>.] - ETA: 0s - loss: 0.0123 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0123 - accuracy: 0.9937
Epoch 13/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0072 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.0097 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0112 - accuracy:   48/1083 [>.............................] - ETA: 3s - loss: 0.0114 - accuracy:   63/1083 [>.............................] - ETA: 3s - loss: 0.0102 - accuracy:   78/1083 [=>............................] - ETA: 3s - loss: 0.0121 - accuracy:   93/1083 [=>............................] - ETA: 3s - loss: 0.0119 - accuracy:  106/1083 [=>............................] - ETA: 3s - loss: 0.0123 - accuracy:  121/1083 [==>...........................] - ETA: 3s - loss: 0.0126 - accuracy:  137/1083 [==>...........................] - ETA: 3s - loss: 0.0124 - accuracy:  152/1083 [===>..........................] - ETA: 3s - loss: 0.0125 - accuracy:  168/1083 [===>..........................] - ETA: 3s - loss: 0.0126 - accuracy:  183/1083 [====>.........................] - ETA: 3s - loss: 0.0126 - accuracy:  199/1083 [====>.........................] - ETA: 2s - loss: 0.0126 - accuracy:  213/1083 [====>.........................] - ETA: 2s - loss: 0.0124 - accuracy:  229/1083 [=====>........................] - ETA: 2s - loss: 0.0125 - accuracy:  243/1083 [=====>........................] - ETA: 2s - loss: 0.0123 - accuracy:  259/1083 [======>.......................] - ETA: 2s - loss: 0.0122 - accuracy:  274/1083 [======>.......................] - ETA: 2s - loss: 0.0119 - accuracy:  290/1083 [=======>......................] - ETA: 2s - loss: 0.0117 - accuracy:  306/1083 [=======>......................] - ETA: 2s - loss: 0.0116 - accuracy:  321/1083 [=======>......................] - ETA: 2s - loss: 0.0115 - accuracy:  336/1083 [========>.....................] - ETA: 2s - loss: 0.0114 - accuracy:  351/1083 [========>.....................] - ETA: 2s - loss: 0.0116 - accuracy:  366/1083 [=========>....................] - ETA: 2s - loss: 0.0114 - accuracy:  382/1083 [=========>....................] - ETA: 2s - loss: 0.0117 - accuracy:  397/1083 [=========>....................] - ETA: 2s - loss: 0.0118 - accuracy:  413/1083 [==========>...................] - ETA: 2s - loss: 0.0115 - accuracy:  428/1083 [==========>...................] - ETA: 2s - loss: 0.0116 - accuracy:  444/1083 [===========>..................] - ETA: 2s - loss: 0.0115 - accuracy:  459/1083 [===========>..................] - ETA: 2s - loss: 0.0115 - accuracy:  474/1083 [============>.................] - ETA: 2s - loss: 0.0114 - accuracy:  489/1083 [============>.................] - ETA: 2s - loss: 0.0113 - accuracy:  505/1083 [============>.................] - ETA: 1s - loss: 0.0114 - accuracy:  520/1083 [=============>................] - ETA: 1s - loss: 0.0113 - accuracy:  536/1083 [=============>................] - ETA: 1s - loss: 0.0111 - accuracy:  550/1083 [==============>...............] - ETA: 1s - loss: 0.0110 - accuracy:  565/1083 [==============>...............] - ETA: 1s - loss: 0.0112 - accuracy:  579/1083 [===============>..............] - ETA: 1s - loss: 0.0112 - accuracy:  594/1083 [===============>..............] - ETA: 1s - loss: 0.0112 - accuracy:  609/1083 [===============>..............] - ETA: 1s - loss: 0.0110 - accuracy:  625/1083 [================>.............] - ETA: 1s - loss: 0.0109 - accuracy:  640/1083 [================>.............] - ETA: 1s - loss: 0.0109 - accuracy:  656/1083 [=================>............] - ETA: 1s - loss: 0.0109 - accuracy:  672/1083 [=================>............] - ETA: 1s - loss: 0.0109 - accuracy:  689/1083 [==================>...........] - ETA: 1s - loss: 0.0107 - accuracy:  702/1083 [==================>...........] - ETA: 1s - loss: 0.0107 - accuracy:  717/1083 [==================>...........] - ETA: 1s - loss: 0.0105 - accuracy:  731/1083 [===================>..........] - ETA: 1s - loss: 0.0106 - accuracy:  746/1083 [===================>..........] - ETA: 1s - loss: 0.0106 - accuracy:  762/1083 [====================>.........] - ETA: 1s - loss: 0.0107 - accuracy:  778/1083 [====================>.........] - ETA: 1s - loss: 0.0106 - accuracy:  794/1083 [====================>.........] - ETA: 0s - loss: 0.0107 - accuracy:  810/1083 [=====================>........] - ETA: 0s - loss: 0.0107 - accuracy:  824/1083 [=====================>........] - ETA: 0s - loss: 0.0108 - accuracy:  840/1083 [======================>.......] - ETA: 0s - loss: 0.0109 - accuracy:  855/1083 [======================>.......] - ETA: 0s - loss: 0.0111 - accuracy:  871/1083 [=======================>......] - ETA: 0s - loss: 0.0110 - accuracy:  886/1083 [=======================>......] - ETA: 0s - loss: 0.0111 - accuracy:  902/1083 [=======================>......] - ETA: 0s - loss: 0.0111 - accuracy:  918/1083 [========================>.....] - ETA: 0s - loss: 0.0111 - accuracy:  933/1083 [========================>.....] - ETA: 0s - loss: 0.0110 - accuracy:  948/1083 [=========================>....] - ETA: 0s - loss: 0.0109 - accuracy:  964/1083 [=========================>....] - ETA: 0s - loss: 0.0108 - accuracy:  979/1083 [==========================>...] - ETA: 0s - loss: 0.0108 - accuracy:  995/1083 [==========================>...] - ETA: 0s - loss: 0.0108 - accuracy: 1010/1083 [==========================>...] - ETA: 0s - loss: 0.0107 - accuracy: 1026/1083 [===========================>..] - ETA: 0s - loss: 0.0108 - accuracy: 1041/1083 [===========================>..] - ETA: 0s - loss: 0.0109 - accuracy: 1057/1083 [============================>.] - ETA: 0s - loss: 0.0109 - accuracy: 1072/1083 [============================>.] - ETA: 0s - loss: 0.0110 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0109 - accuracy: 0.9947
Epoch 14/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0081 - accuracy:   15/1083 [..............................] - ETA: 3s - loss: 0.0077 - accuracy:   30/1083 [..............................] - ETA: 3s - loss: 0.0073 - accuracy:   45/1083 [>.............................] - ETA: 3s - loss: 0.0069 - accuracy:   61/1083 [>.............................] - ETA: 3s - loss: 0.0068 - accuracy:   77/1083 [=>............................] - ETA: 3s - loss: 0.0082 - accuracy:   92/1083 [=>............................] - ETA: 3s - loss: 0.0089 - accuracy:  107/1083 [=>............................] - ETA: 3s - loss: 0.0084 - accuracy:  123/1083 [==>...........................] - ETA: 3s - loss: 0.0087 - accuracy:  138/1083 [==>...........................] - ETA: 3s - loss: 0.0090 - accuracy:  154/1083 [===>..........................] - ETA: 3s - loss: 0.0094 - accuracy:  169/1083 [===>..........................] - ETA: 3s - loss: 0.0098 - accuracy:  185/1083 [====>.........................] - ETA: 3s - loss: 0.0097 - accuracy:  201/1083 [====>.........................] - ETA: 2s - loss: 0.0100 - accuracy:  216/1083 [====>.........................] - ETA: 2s - loss: 0.0097 - accuracy:  231/1083 [=====>........................] - ETA: 2s - loss: 0.0094 - accuracy:  247/1083 [=====>........................] - ETA: 2s - loss: 0.0095 - accuracy:  262/1083 [======>.......................] - ETA: 2s - loss: 0.0095 - accuracy:  277/1083 [======>.......................] - ETA: 2s - loss: 0.0092 - accuracy:  293/1083 [=======>......................] - ETA: 2s - loss: 0.0091 - accuracy:  308/1083 [=======>......................] - ETA: 2s - loss: 0.0092 - accuracy:  324/1083 [=======>......................] - ETA: 2s - loss: 0.0090 - accuracy:  340/1083 [========>.....................] - ETA: 2s - loss: 0.0091 - accuracy:  354/1083 [========>.....................] - ETA: 2s - loss: 0.0091 - accuracy:  369/1083 [=========>....................] - ETA: 2s - loss: 0.0089 - accuracy:  384/1083 [=========>....................] - ETA: 2s - loss: 0.0090 - accuracy:  399/1083 [==========>...................] - ETA: 2s - loss: 0.0091 - accuracy:  414/1083 [==========>...................] - ETA: 2s - loss: 0.0092 - accuracy:  430/1083 [==========>...................] - ETA: 2s - loss: 0.0093 - accuracy:  445/1083 [===========>..................] - ETA: 2s - loss: 0.0097 - accuracy:  461/1083 [===========>..................] - ETA: 2s - loss: 0.0097 - accuracy:  477/1083 [============>.................] - ETA: 2s - loss: 0.0097 - accuracy:  493/1083 [============>.................] - ETA: 1s - loss: 0.0096 - accuracy:  509/1083 [=============>................] - ETA: 1s - loss: 0.0095 - accuracy:  525/1083 [=============>................] - ETA: 1s - loss: 0.0094 - accuracy:  541/1083 [=============>................] - ETA: 1s - loss: 0.0095 - accuracy:  557/1083 [==============>...............] - ETA: 1s - loss: 0.0095 - accuracy:  573/1083 [==============>...............] - ETA: 1s - loss: 0.0094 - accuracy:  588/1083 [===============>..............] - ETA: 1s - loss: 0.0093 - accuracy:  604/1083 [===============>..............] - ETA: 1s - loss: 0.0094 - accuracy:  620/1083 [================>.............] - ETA: 1s - loss: 0.0093 - accuracy:  633/1083 [================>.............] - ETA: 1s - loss: 0.0094 - accuracy:  648/1083 [================>.............] - ETA: 1s - loss: 0.0094 - accuracy:  663/1083 [=================>............] - ETA: 1s - loss: 0.0093 - accuracy:  677/1083 [=================>............] - ETA: 1s - loss: 0.0093 - accuracy:  690/1083 [==================>...........] - ETA: 1s - loss: 0.0093 - accuracy:  706/1083 [==================>...........] - ETA: 1s - loss: 0.0092 - accuracy:  717/1083 [==================>...........] - ETA: 1s - loss: 0.0092 - accuracy:  731/1083 [===================>..........] - ETA: 1s - loss: 0.0092 - accuracy:  746/1083 [===================>..........] - ETA: 1s - loss: 0.0092 - accuracy:  762/1083 [====================>.........] - ETA: 1s - loss: 0.0092 - accuracy:  777/1083 [====================>.........] - ETA: 1s - loss: 0.0092 - accuracy:  792/1083 [====================>.........] - ETA: 0s - loss: 0.0092 - accuracy:  807/1083 [=====================>........] - ETA: 0s - loss: 0.0093 - accuracy:  823/1083 [=====================>........] - ETA: 0s - loss: 0.0092 - accuracy:  838/1083 [======================>.......] - ETA: 0s - loss: 0.0091 - accuracy:  854/1083 [======================>.......] - ETA: 0s - loss: 0.0091 - accuracy:  869/1083 [=======================>......] - ETA: 0s - loss: 0.0092 - accuracy:  884/1083 [=======================>......] - ETA: 0s - loss: 0.0092 - accuracy:  898/1083 [=======================>......] - ETA: 0s - loss: 0.0092 - accuracy:  914/1083 [========================>.....] - ETA: 0s - loss: 0.0092 - accuracy:  929/1083 [========================>.....] - ETA: 0s - loss: 0.0093 - accuracy:  945/1083 [=========================>....] - ETA: 0s - loss: 0.0094 - accuracy:  961/1083 [=========================>....] - ETA: 0s - loss: 0.0095 - accuracy:  976/1083 [==========================>...] - ETA: 0s - loss: 0.0095 - accuracy:  992/1083 [==========================>...] - ETA: 0s - loss: 0.0095 - accuracy: 1008/1083 [==========================>...] - ETA: 0s - loss: 0.0095 - accuracy: 1023/1083 [===========================>..] - ETA: 0s - loss: 0.0096 - accuracy: 1039/1083 [===========================>..] - ETA: 0s - loss: 0.0096 - accuracy: 1054/1083 [============================>.] - ETA: 0s - loss: 0.0096 - accuracy: 1070/1083 [============================>.] - ETA: 0s - loss: 0.0096 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0096 - accuracy: 0.9953
Epoch 15/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0057 - accuracy:   15/1083 [..............................] - ETA: 3s - loss: 0.0060 - accuracy:   30/1083 [..............................] - ETA: 3s - loss: 0.0072 - accuracy:   45/1083 [>.............................] - ETA: 3s - loss: 0.0076 - accuracy:   61/1083 [>.............................] - ETA: 3s - loss: 0.0082 - accuracy:   77/1083 [=>............................] - ETA: 3s - loss: 0.0086 - accuracy:   93/1083 [=>............................] - ETA: 3s - loss: 0.0078 - accuracy:  109/1083 [==>...........................] - ETA: 3s - loss: 0.0077 - accuracy:  124/1083 [==>...........................] - ETA: 3s - loss: 0.0076 - accuracy:  139/1083 [==>...........................] - ETA: 3s - loss: 0.0073 - accuracy:  153/1083 [===>..........................] - ETA: 3s - loss: 0.0076 - accuracy:  169/1083 [===>..........................] - ETA: 3s - loss: 0.0075 - accuracy:  184/1083 [====>.........................] - ETA: 3s - loss: 0.0076 - accuracy:  199/1083 [====>.........................] - ETA: 2s - loss: 0.0074 - accuracy:  212/1083 [====>.........................] - ETA: 2s - loss: 0.0073 - accuracy:  227/1083 [=====>........................] - ETA: 2s - loss: 0.0073 - accuracy:  242/1083 [=====>........................] - ETA: 2s - loss: 0.0076 - accuracy:  259/1083 [======>.......................] - ETA: 2s - loss: 0.0075 - accuracy:  273/1083 [======>.......................] - ETA: 2s - loss: 0.0078 - accuracy:  289/1083 [=======>......................] - ETA: 2s - loss: 0.0076 - accuracy:  301/1083 [=======>......................] - ETA: 2s - loss: 0.0076 - accuracy:  317/1083 [=======>......................] - ETA: 2s - loss: 0.0077 - accuracy:  331/1083 [========>.....................] - ETA: 2s - loss: 0.0079 - accuracy:  347/1083 [========>.....................] - ETA: 2s - loss: 0.0078 - accuracy:  362/1083 [=========>....................] - ETA: 2s - loss: 0.0078 - accuracy:  377/1083 [=========>....................] - ETA: 2s - loss: 0.0079 - accuracy:  390/1083 [=========>....................] - ETA: 2s - loss: 0.0079 - accuracy:  402/1083 [==========>...................] - ETA: 2s - loss: 0.0080 - accuracy:  417/1083 [==========>...................] - ETA: 2s - loss: 0.0078 - accuracy:  432/1083 [==========>...................] - ETA: 2s - loss: 0.0079 - accuracy:  446/1083 [===========>..................] - ETA: 2s - loss: 0.0079 - accuracy:  461/1083 [===========>..................] - ETA: 2s - loss: 0.0080 - accuracy:  476/1083 [============>.................] - ETA: 2s - loss: 0.0080 - accuracy:  492/1083 [============>.................] - ETA: 2s - loss: 0.0080 - accuracy:  507/1083 [=============>................] - ETA: 1s - loss: 0.0081 - accuracy:  523/1083 [=============>................] - ETA: 1s - loss: 0.0083 - accuracy:  538/1083 [=============>................] - ETA: 1s - loss: 0.0082 - accuracy:  555/1083 [==============>...............] - ETA: 1s - loss: 0.0083 - accuracy:  571/1083 [==============>...............] - ETA: 1s - loss: 0.0083 - accuracy:  587/1083 [===============>..............] - ETA: 1s - loss: 0.0082 - accuracy:  602/1083 [===============>..............] - ETA: 1s - loss: 0.0082 - accuracy:  617/1083 [================>.............] - ETA: 1s - loss: 0.0081 - accuracy:  631/1083 [================>.............] - ETA: 1s - loss: 0.0081 - accuracy:  646/1083 [================>.............] - ETA: 1s - loss: 0.0082 - accuracy:  661/1083 [=================>............] - ETA: 1s - loss: 0.0082 - accuracy:  676/1083 [=================>............] - ETA: 1s - loss: 0.0082 - accuracy:  691/1083 [==================>...........] - ETA: 1s - loss: 0.0082 - accuracy:  707/1083 [==================>...........] - ETA: 1s - loss: 0.0081 - accuracy:  722/1083 [===================>..........] - ETA: 1s - loss: 0.0081 - accuracy:  735/1083 [===================>..........] - ETA: 1s - loss: 0.0081 - accuracy:  749/1083 [===================>..........] - ETA: 1s - loss: 0.0081 - accuracy:  765/1083 [====================>.........] - ETA: 1s - loss: 0.0080 - accuracy:  781/1083 [====================>.........] - ETA: 1s - loss: 0.0079 - accuracy:  797/1083 [=====================>........] - ETA: 0s - loss: 0.0079 - accuracy:  812/1083 [=====================>........] - ETA: 0s - loss: 0.0079 - accuracy:  828/1083 [=====================>........] - ETA: 0s - loss: 0.0079 - accuracy:  844/1083 [======================>.......] - ETA: 0s - loss: 0.0079 - accuracy:  860/1083 [======================>.......] - ETA: 0s - loss: 0.0079 - accuracy:  875/1083 [=======================>......] - ETA: 0s - loss: 0.0079 - accuracy:  889/1083 [=======================>......] - ETA: 0s - loss: 0.0079 - accuracy:  904/1083 [========================>.....] - ETA: 0s - loss: 0.0079 - accuracy:  920/1083 [========================>.....] - ETA: 0s - loss: 0.0079 - accuracy:  935/1083 [========================>.....] - ETA: 0s - loss: 0.0079 - accuracy:  950/1083 [=========================>....] - ETA: 0s - loss: 0.0079 - accuracy:  966/1083 [=========================>....] - ETA: 0s - loss: 0.0078 - accuracy:  982/1083 [==========================>...] - ETA: 0s - loss: 0.0078 - accuracy:  997/1083 [==========================>...] - ETA: 0s - loss: 0.0078 - accuracy: 1013/1083 [===========================>..] - ETA: 0s - loss: 0.0078 - accuracy: 1028/1083 [===========================>..] - ETA: 0s - loss: 0.0078 - accuracy: 1044/1083 [===========================>..] - ETA: 0s - loss: 0.0078 - accuracy: 1059/1083 [============================>.] - ETA: 0s - loss: 0.0078 - accuracy: 1074/1083 [============================>.] - ETA: 0s - loss: 0.0077 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0077 - accuracy: 0.9967
Epoch 16/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0016 - accuracy:   16/1083 [..............................] - ETA: 3s - loss: 0.0065 - accuracy:   32/1083 [..............................] - ETA: 3s - loss: 0.0059 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0056 - accuracy:   62/1083 [>.............................] - ETA: 3s - loss: 0.0075 - accuracy:   78/1083 [=>............................] - ETA: 3s - loss: 0.0070 - accuracy:   92/1083 [=>............................] - ETA: 3s - loss: 0.0075 - accuracy:  108/1083 [=>............................] - ETA: 3s - loss: 0.0076 - accuracy:  123/1083 [==>...........................] - ETA: 3s - loss: 0.0078 - accuracy:  139/1083 [==>...........................] - ETA: 3s - loss: 0.0075 - accuracy:  155/1083 [===>..........................] - ETA: 3s - loss: 0.0072 - accuracy:  171/1083 [===>..........................] - ETA: 3s - loss: 0.0074 - accuracy:  187/1083 [====>.........................] - ETA: 3s - loss: 0.0073 - accuracy:  203/1083 [====>.........................] - ETA: 2s - loss: 0.0071 - accuracy:  219/1083 [=====>........................] - ETA: 2s - loss: 0.0081 - accuracy:  235/1083 [=====>........................] - ETA: 2s - loss: 0.0081 - accuracy:  250/1083 [=====>........................] - ETA: 2s - loss: 0.0086 - accuracy:  265/1083 [======>.......................] - ETA: 2s - loss: 0.0086 - accuracy:  280/1083 [======>.......................] - ETA: 2s - loss: 0.0086 - accuracy:  295/1083 [=======>......................] - ETA: 2s - loss: 0.0086 - accuracy:  310/1083 [=======>......................] - ETA: 2s - loss: 0.0083 - accuracy:  326/1083 [========>.....................] - ETA: 2s - loss: 0.0082 - accuracy:  341/1083 [========>.....................] - ETA: 2s - loss: 0.0080 - accuracy:  357/1083 [========>.....................] - ETA: 2s - loss: 0.0079 - accuracy:  371/1083 [=========>....................] - ETA: 2s - loss: 0.0079 - accuracy:  386/1083 [=========>....................] - ETA: 2s - loss: 0.0079 - accuracy:  400/1083 [==========>...................] - ETA: 2s - loss: 0.0079 - accuracy:  414/1083 [==========>...................] - ETA: 2s - loss: 0.0079 - accuracy:  429/1083 [==========>...................] - ETA: 2s - loss: 0.0078 - accuracy:  445/1083 [===========>..................] - ETA: 2s - loss: 0.0077 - accuracy:  460/1083 [===========>..................] - ETA: 2s - loss: 0.0077 - accuracy:  475/1083 [============>.................] - ETA: 2s - loss: 0.0075 - accuracy:  490/1083 [============>.................] - ETA: 2s - loss: 0.0075 - accuracy:  506/1083 [=============>................] - ETA: 1s - loss: 0.0074 - accuracy:  521/1083 [=============>................] - ETA: 1s - loss: 0.0075 - accuracy:  536/1083 [=============>................] - ETA: 1s - loss: 0.0076 - accuracy:  550/1083 [==============>...............] - ETA: 1s - loss: 0.0076 - accuracy:  566/1083 [==============>...............] - ETA: 1s - loss: 0.0075 - accuracy:  580/1083 [===============>..............] - ETA: 1s - loss: 0.0075 - accuracy:  595/1083 [===============>..............] - ETA: 1s - loss: 0.0075 - accuracy:  611/1083 [===============>..............] - ETA: 1s - loss: 0.0074 - accuracy:  627/1083 [================>.............] - ETA: 1s - loss: 0.0074 - accuracy:  643/1083 [================>.............] - ETA: 1s - loss: 0.0076 - accuracy:  658/1083 [=================>............] - ETA: 1s - loss: 0.0075 - accuracy:  673/1083 [=================>............] - ETA: 1s - loss: 0.0075 - accuracy:  689/1083 [==================>...........] - ETA: 1s - loss: 0.0075 - accuracy:  704/1083 [==================>...........] - ETA: 1s - loss: 0.0075 - accuracy:  720/1083 [==================>...........] - ETA: 1s - loss: 0.0075 - accuracy:  734/1083 [===================>..........] - ETA: 1s - loss: 0.0074 - accuracy:  749/1083 [===================>..........] - ETA: 1s - loss: 0.0074 - accuracy:  764/1083 [====================>.........] - ETA: 1s - loss: 0.0074 - accuracy:  780/1083 [====================>.........] - ETA: 1s - loss: 0.0074 - accuracy:  795/1083 [=====================>........] - ETA: 0s - loss: 0.0074 - accuracy:  811/1083 [=====================>........] - ETA: 0s - loss: 0.0074 - accuracy:  825/1083 [=====================>........] - ETA: 0s - loss: 0.0075 - accuracy:  839/1083 [======================>.......] - ETA: 0s - loss: 0.0075 - accuracy:  853/1083 [======================>.......] - ETA: 0s - loss: 0.0075 - accuracy:  869/1083 [=======================>......] - ETA: 0s - loss: 0.0074 - accuracy:  884/1083 [=======================>......] - ETA: 0s - loss: 0.0074 - accuracy:  900/1083 [=======================>......] - ETA: 0s - loss: 0.0074 - accuracy:  915/1083 [========================>.....] - ETA: 0s - loss: 0.0075 - accuracy:  930/1083 [========================>.....] - ETA: 0s - loss: 0.0075 - accuracy:  945/1083 [=========================>....] - ETA: 0s - loss: 0.0074 - accuracy:  961/1083 [=========================>....] - ETA: 0s - loss: 0.0074 - accuracy:  978/1083 [==========================>...] - ETA: 0s - loss: 0.0075 - accuracy:  992/1083 [==========================>...] - ETA: 0s - loss: 0.0075 - accuracy: 1008/1083 [==========================>...] - ETA: 0s - loss: 0.0075 - accuracy: 1024/1083 [===========================>..] - ETA: 0s - loss: 0.0075 - accuracy: 1040/1083 [===========================>..] - ETA: 0s - loss: 0.0074 - accuracy: 1056/1083 [============================>.] - ETA: 0s - loss: 0.0074 - accuracy: 1071/1083 [============================>.] - ETA: 0s - loss: 0.0074 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0074 - accuracy: 0.9961
Epoch 17/20
   1/1083 [..............................] - ETA: 3s - loss: 0.0114 - accuracy:   15/1083 [..............................] - ETA: 3s - loss: 0.0045 - accuracy:   31/1083 [..............................] - ETA: 3s - loss: 0.0065 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0069 - accuracy:   61/1083 [>.............................] - ETA: 3s - loss: 0.0071 - accuracy:   77/1083 [=>............................] - ETA: 3s - loss: 0.0073 - accuracy:   92/1083 [=>............................] - ETA: 3s - loss: 0.0079 - accuracy:  107/1083 [=>............................] - ETA: 3s - loss: 0.0078 - accuracy:  123/1083 [==>...........................] - ETA: 3s - loss: 0.0075 - accuracy:  136/1083 [==>...........................] - ETA: 3s - loss: 0.0075 - accuracy:  145/1083 [===>..........................] - ETA: 3s - loss: 0.0078 - accuracy:  157/1083 [===>..........................] - ETA: 3s - loss: 0.0076 - accuracy:  172/1083 [===>..........................] - ETA: 3s - loss: 0.0073 - accuracy:  187/1083 [====>.........................] - ETA: 3s - loss: 0.0072 - accuracy:  201/1083 [====>.........................] - ETA: 3s - loss: 0.0074 - accuracy:  217/1083 [=====>........................] - ETA: 3s - loss: 0.0072 - accuracy:  232/1083 [=====>........................] - ETA: 3s - loss: 0.0071 - accuracy:  248/1083 [=====>........................] - ETA: 2s - loss: 0.0069 - accuracy:  263/1083 [======>.......................] - ETA: 2s - loss: 0.0067 - accuracy:  277/1083 [======>.......................] - ETA: 2s - loss: 0.0065 - accuracy:  291/1083 [=======>......................] - ETA: 2s - loss: 0.0066 - accuracy:  306/1083 [=======>......................] - ETA: 2s - loss: 0.0066 - accuracy:  321/1083 [=======>......................] - ETA: 2s - loss: 0.0064 - accuracy:  336/1083 [========>.....................] - ETA: 2s - loss: 0.0064 - accuracy:  351/1083 [========>.....................] - ETA: 2s - loss: 0.0063 - accuracy:  366/1083 [=========>....................] - ETA: 2s - loss: 0.0062 - accuracy:  381/1083 [=========>....................] - ETA: 2s - loss: 0.0060 - accuracy:  396/1083 [=========>....................] - ETA: 2s - loss: 0.0059 - accuracy:  411/1083 [==========>...................] - ETA: 2s - loss: 0.0058 - accuracy:  427/1083 [==========>...................] - ETA: 2s - loss: 0.0058 - accuracy:  443/1083 [===========>..................] - ETA: 2s - loss: 0.0059 - accuracy:  458/1083 [===========>..................] - ETA: 2s - loss: 0.0059 - accuracy:  473/1083 [============>.................] - ETA: 2s - loss: 0.0059 - accuracy:  486/1083 [============>.................] - ETA: 2s - loss: 0.0058 - accuracy:  501/1083 [============>.................] - ETA: 2s - loss: 0.0058 - accuracy:  517/1083 [=============>................] - ETA: 1s - loss: 0.0057 - accuracy:  532/1083 [=============>................] - ETA: 1s - loss: 0.0058 - accuracy:  548/1083 [==============>...............] - ETA: 1s - loss: 0.0059 - accuracy:  564/1083 [==============>...............] - ETA: 1s - loss: 0.0062 - accuracy:  580/1083 [===============>..............] - ETA: 1s - loss: 0.0062 - accuracy:  596/1083 [===============>..............] - ETA: 1s - loss: 0.0061 - accuracy:  612/1083 [===============>..............] - ETA: 1s - loss: 0.0061 - accuracy:  626/1083 [================>.............] - ETA: 1s - loss: 0.0061 - accuracy:  641/1083 [================>.............] - ETA: 1s - loss: 0.0061 - accuracy:  656/1083 [=================>............] - ETA: 1s - loss: 0.0061 - accuracy:  671/1083 [=================>............] - ETA: 1s - loss: 0.0061 - accuracy:  686/1083 [==================>...........] - ETA: 1s - loss: 0.0062 - accuracy:  702/1083 [==================>...........] - ETA: 1s - loss: 0.0061 - accuracy:  718/1083 [==================>...........] - ETA: 1s - loss: 0.0062 - accuracy:  734/1083 [===================>..........] - ETA: 1s - loss: 0.0063 - accuracy:  749/1083 [===================>..........] - ETA: 1s - loss: 0.0064 - accuracy:  766/1083 [====================>.........] - ETA: 1s - loss: 0.0064 - accuracy:  781/1083 [====================>.........] - ETA: 1s - loss: 0.0063 - accuracy:  797/1083 [=====================>........] - ETA: 0s - loss: 0.0063 - accuracy:  812/1083 [=====================>........] - ETA: 0s - loss: 0.0063 - accuracy:  827/1083 [=====================>........] - ETA: 0s - loss: 0.0064 - accuracy:  842/1083 [======================>.......] - ETA: 0s - loss: 0.0064 - accuracy:  858/1083 [======================>.......] - ETA: 0s - loss: 0.0064 - accuracy:  874/1083 [=======================>......] - ETA: 0s - loss: 0.0064 - accuracy:  890/1083 [=======================>......] - ETA: 0s - loss: 0.0064 - accuracy:  905/1083 [========================>.....] - ETA: 0s - loss: 0.0064 - accuracy:  921/1083 [========================>.....] - ETA: 0s - loss: 0.0064 - accuracy:  935/1083 [========================>.....] - ETA: 0s - loss: 0.0063 - accuracy:  950/1083 [=========================>....] - ETA: 0s - loss: 0.0063 - accuracy:  966/1083 [=========================>....] - ETA: 0s - loss: 0.0063 - accuracy:  982/1083 [==========================>...] - ETA: 0s - loss: 0.0063 - accuracy:  998/1083 [==========================>...] - ETA: 0s - loss: 0.0062 - accuracy: 1014/1083 [===========================>..] - ETA: 0s - loss: 0.0063 - accuracy: 1030/1083 [===========================>..] - ETA: 0s - loss: 0.0063 - accuracy: 1046/1083 [===========================>..] - ETA: 0s - loss: 0.0063 - accuracy: 1061/1083 [============================>.] - ETA: 0s - loss: 0.0063 - accuracy: 1075/1083 [============================>.] - ETA: 0s - loss: 0.0063 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0062 - accuracy: 0.9975
Epoch 18/20
   1/1083 [..............................] - ETA: 3s - loss: 2.6458e-05 - accura  16/1083 [..............................] - ETA: 3s - loss: 0.0044 - accuracy:   31/1083 [..............................] - ETA: 3s - loss: 0.0044 - accuracy:   47/1083 [>.............................] - ETA: 3s - loss: 0.0051 - accuracy:   59/1083 [>.............................] - ETA: 3s - loss: 0.0060 - accuracy:   75/1083 [=>............................] - ETA: 3s - loss: 0.0057 - accuracy:   91/1083 [=>............................] - ETA: 3s - loss: 0.0051 - accuracy:  106/1083 [=>............................] - ETA: 3s - loss: 0.0050 - accuracy:  121/1083 [==>...........................] - ETA: 3s - loss: 0.0052 - accuracy:  137/1083 [==>...........................] - ETA: 3s - loss: 0.0048 - accuracy:  150/1083 [===>..........................] - ETA: 3s - loss: 0.0048 - accuracy:  166/1083 [===>..........................] - ETA: 3s - loss: 0.0046 - accuracy:  181/1083 [====>.........................] - ETA: 3s - loss: 0.0047 - accuracy:  196/1083 [====>.........................] - ETA: 3s - loss: 0.0046 - accuracy:  212/1083 [====>.........................] - ETA: 2s - loss: 0.0047 - accuracy:  228/1083 [=====>........................] - ETA: 2s - loss: 0.0048 - accuracy:  243/1083 [=====>........................] - ETA: 2s - loss: 0.0050 - accuracy:  259/1083 [======>.......................] - ETA: 2s - loss: 0.0049 - accuracy:  274/1083 [======>.......................] - ETA: 2s - loss: 0.0048 - accuracy:  290/1083 [=======>......................] - ETA: 2s - loss: 0.0047 - accuracy:  305/1083 [=======>......................] - ETA: 2s - loss: 0.0047 - accuracy:  321/1083 [=======>......................] - ETA: 2s - loss: 0.0047 - accuracy:  336/1083 [========>.....................] - ETA: 2s - loss: 0.0046 - accuracy:  352/1083 [========>.....................] - ETA: 2s - loss: 0.0047 - accuracy:  368/1083 [=========>....................] - ETA: 2s - loss: 0.0047 - accuracy:  384/1083 [=========>....................] - ETA: 2s - loss: 0.0048 - accuracy:  399/1083 [==========>...................] - ETA: 2s - loss: 0.0049 - accuracy:  415/1083 [==========>...................] - ETA: 2s - loss: 0.0049 - accuracy:  430/1083 [==========>...................] - ETA: 2s - loss: 0.0049 - accuracy:  443/1083 [===========>..................] - ETA: 2s - loss: 0.0049 - accuracy:  457/1083 [===========>..................] - ETA: 2s - loss: 0.0050 - accuracy:  473/1083 [============>.................] - ETA: 2s - loss: 0.0049 - accuracy:  488/1083 [============>.................] - ETA: 2s - loss: 0.0048 - accuracy:  504/1083 [============>.................] - ETA: 1s - loss: 0.0049 - accuracy:  520/1083 [=============>................] - ETA: 1s - loss: 0.0050 - accuracy:  535/1083 [=============>................] - ETA: 1s - loss: 0.0051 - accuracy:  549/1083 [==============>...............] - ETA: 1s - loss: 0.0051 - accuracy:  565/1083 [==============>...............] - ETA: 1s - loss: 0.0052 - accuracy:  578/1083 [===============>..............] - ETA: 1s - loss: 0.0051 - accuracy:  592/1083 [===============>..............] - ETA: 1s - loss: 0.0051 - accuracy:  607/1083 [===============>..............] - ETA: 1s - loss: 0.0051 - accuracy:  623/1083 [================>.............] - ETA: 1s - loss: 0.0051 - accuracy:  638/1083 [================>.............] - ETA: 1s - loss: 0.0052 - accuracy:  654/1083 [=================>............] - ETA: 1s - loss: 0.0052 - accuracy:  669/1083 [=================>............] - ETA: 1s - loss: 0.0051 - accuracy:  682/1083 [=================>............] - ETA: 1s - loss: 0.0051 - accuracy:  695/1083 [==================>...........] - ETA: 1s - loss: 0.0051 - accuracy:  710/1083 [==================>...........] - ETA: 1s - loss: 0.0052 - accuracy:  723/1083 [===================>..........] - ETA: 1s - loss: 0.0052 - accuracy:  738/1083 [===================>..........] - ETA: 1s - loss: 0.0052 - accuracy:  753/1083 [===================>..........] - ETA: 1s - loss: 0.0053 - accuracy:  769/1083 [====================>.........] - ETA: 1s - loss: 0.0053 - accuracy:  784/1083 [====================>.........] - ETA: 1s - loss: 0.0053 - accuracy:  800/1083 [=====================>........] - ETA: 0s - loss: 0.0052 - accuracy:  815/1083 [=====================>........] - ETA: 0s - loss: 0.0052 - accuracy:  831/1083 [======================>.......] - ETA: 0s - loss: 0.0052 - accuracy:  846/1083 [======================>.......] - ETA: 0s - loss: 0.0052 - accuracy:  862/1083 [======================>.......] - ETA: 0s - loss: 0.0052 - accuracy:  877/1083 [=======================>......] - ETA: 0s - loss: 0.0052 - accuracy:  893/1083 [=======================>......] - ETA: 0s - loss: 0.0052 - accuracy:  908/1083 [========================>.....] - ETA: 0s - loss: 0.0051 - accuracy:  924/1083 [========================>.....] - ETA: 0s - loss: 0.0051 - accuracy:  939/1083 [=========================>....] - ETA: 0s - loss: 0.0051 - accuracy:  955/1083 [=========================>....] - ETA: 0s - loss: 0.0051 - accuracy:  969/1083 [=========================>....] - ETA: 0s - loss: 0.0052 - accuracy:  982/1083 [==========================>...] - ETA: 0s - loss: 0.0052 - accuracy:  994/1083 [==========================>...] - ETA: 0s - loss: 0.0052 - accuracy: 1006/1083 [==========================>...] - ETA: 0s - loss: 0.0052 - accuracy: 1019/1083 [===========================>..] - ETA: 0s - loss: 0.0053 - accuracy: 1033/1083 [===========================>..] - ETA: 0s - loss: 0.0053 - accuracy: 1047/1083 [============================>.] - ETA: 0s - loss: 0.0053 - accuracy: 1062/1083 [============================>.] - ETA: 0s - loss: 0.0053 - accuracy: 1075/1083 [============================>.] - ETA: 0s - loss: 0.0053 - accuracy: 1083/1083 [==============================] - 4s 3ms/step - loss: 0.0054 - accuracy: 0.9979
Epoch 19/20
   1/1083 [..............................] - ETA: 4s - loss: 0.0110 - accuracy:   14/1083 [..............................] - ETA: 4s - loss: 0.0099 - accuracy:   28/1083 [..............................] - ETA: 4s - loss: 0.0068 - accuracy:   42/1083 [>.............................] - ETA: 4s - loss: 0.0061 - accuracy:   55/1083 [>.............................] - ETA: 4s - loss: 0.0055 - accuracy:   69/1083 [>.............................] - ETA: 3s - loss: 0.0049 - accuracy:   84/1083 [=>............................] - ETA: 3s - loss: 0.0050 - accuracy:   97/1083 [=>............................] - ETA: 3s - loss: 0.0050 - accuracy:  111/1083 [==>...........................] - ETA: 3s - loss: 0.0046 - accuracy:  125/1083 [==>...........................] - ETA: 3s - loss: 0.0044 - accuracy:  135/1083 [==>...........................] - ETA: 3s - loss: 0.0042 - accuracy:  145/1083 [===>..........................] - ETA: 3s - loss: 0.0041 - accuracy:  158/1083 [===>..........................] - ETA: 3s - loss: 0.0040 - accuracy:  170/1083 [===>..........................] - ETA: 3s - loss: 0.0040 - accuracy:  182/1083 [====>.........................] - ETA: 3s - loss: 0.0042 - accuracy:  194/1083 [====>.........................] - ETA: 3s - loss: 0.0044 - accuracy:  207/1083 [====>.........................] - ETA: 3s - loss: 0.0044 - accuracy:  221/1083 [=====>........................] - ETA: 3s - loss: 0.0044 - accuracy:  235/1083 [=====>........................] - ETA: 3s - loss: 0.0043 - accuracy:  248/1083 [=====>........................] - ETA: 3s - loss: 0.0043 - accuracy:  261/1083 [======>.......................] - ETA: 3s - loss: 0.0042 - accuracy:  274/1083 [======>.......................] - ETA: 3s - loss: 0.0042 - accuracy:  288/1083 [======>.......................] - ETA: 3s - loss: 0.0041 - accuracy:  302/1083 [=======>......................] - ETA: 3s - loss: 0.0044 - accuracy:  315/1083 [=======>......................] - ETA: 3s - loss: 0.0045 - accuracy:  326/1083 [========>.....................] - ETA: 3s - loss: 0.0045 - accuracy:  338/1083 [========>.....................] - ETA: 2s - loss: 0.0046 - accuracy:  352/1083 [========>.....................] - ETA: 2s - loss: 0.0047 - accuracy:  364/1083 [=========>....................] - ETA: 2s - loss: 0.0047 - accuracy:  378/1083 [=========>....................] - ETA: 2s - loss: 0.0047 - accuracy:  391/1083 [=========>....................] - ETA: 2s - loss: 0.0046 - accuracy:  404/1083 [==========>...................] - ETA: 2s - loss: 0.0046 - accuracy:  418/1083 [==========>...................] - ETA: 2s - loss: 0.0046 - accuracy:  432/1083 [==========>...................] - ETA: 2s - loss: 0.0046 - accuracy:  444/1083 [===========>..................] - ETA: 2s - loss: 0.0045 - accuracy:  459/1083 [===========>..................] - ETA: 2s - loss: 0.0046 - accuracy:  473/1083 [============>.................] - ETA: 2s - loss: 0.0046 - accuracy:  486/1083 [============>.................] - ETA: 2s - loss: 0.0046 - accuracy:  502/1083 [============>.................] - ETA: 2s - loss: 0.0046 - accuracy:  517/1083 [=============>................] - ETA: 2s - loss: 0.0045 - accuracy:  532/1083 [=============>................] - ETA: 2s - loss: 0.0045 - accuracy:  545/1083 [==============>...............] - ETA: 2s - loss: 0.0046 - accuracy:  561/1083 [==============>...............] - ETA: 2s - loss: 0.0047 - accuracy:  572/1083 [==============>...............] - ETA: 1s - loss: 0.0047 - accuracy:  587/1083 [===============>..............] - ETA: 1s - loss: 0.0048 - accuracy:  603/1083 [===============>..............] - ETA: 1s - loss: 0.0047 - accuracy:  618/1083 [================>.............] - ETA: 1s - loss: 0.0047 - accuracy:  633/1083 [================>.............] - ETA: 1s - loss: 0.0047 - accuracy:  648/1083 [================>.............] - ETA: 1s - loss: 0.0048 - accuracy:  663/1083 [=================>............] - ETA: 1s - loss: 0.0047 - accuracy:  678/1083 [=================>............] - ETA: 1s - loss: 0.0047 - accuracy:  693/1083 [==================>...........] - ETA: 1s - loss: 0.0046 - accuracy:  708/1083 [==================>...........] - ETA: 1s - loss: 0.0046 - accuracy:  723/1083 [===================>..........] - ETA: 1s - loss: 0.0047 - accuracy:  739/1083 [===================>..........] - ETA: 1s - loss: 0.0046 - accuracy:  753/1083 [===================>..........] - ETA: 1s - loss: 0.0046 - accuracy:  769/1083 [====================>.........] - ETA: 1s - loss: 0.0046 - accuracy:  783/1083 [====================>.........] - ETA: 1s - loss: 0.0046 - accuracy:  799/1083 [=====================>........] - ETA: 1s - loss: 0.0046 - accuracy:  813/1083 [=====================>........] - ETA: 1s - loss: 0.0046 - accuracy:  827/1083 [=====================>........] - ETA: 0s - loss: 0.0045 - accuracy:  842/1083 [======================>.......] - ETA: 0s - loss: 0.0045 - accuracy:  858/1083 [======================>.......] - ETA: 0s - loss: 0.0045 - accuracy:  872/1083 [=======================>......] - ETA: 0s - loss: 0.0045 - accuracy:  888/1083 [=======================>......] - ETA: 0s - loss: 0.0045 - accuracy:  903/1083 [========================>.....] - ETA: 0s - loss: 0.0045 - accuracy:  916/1083 [========================>.....] - ETA: 0s - loss: 0.0045 - accuracy:  931/1083 [========================>.....] - ETA: 0s - loss: 0.0045 - accuracy:  947/1083 [=========================>....] - ETA: 0s - loss: 0.0045 - accuracy:  962/1083 [=========================>....] - ETA: 0s - loss: 0.0045 - accuracy:  978/1083 [==========================>...] - ETA: 0s - loss: 0.0044 - accuracy:  993/1083 [==========================>...] - ETA: 0s - loss: 0.0045 - accuracy: 1004/1083 [==========================>...] - ETA: 0s - loss: 0.0044 - accuracy: 1018/1083 [===========================>..] - ETA: 0s - loss: 0.0044 - accuracy: 1031/1083 [===========================>..] - ETA: 0s - loss: 0.0044 - accuracy: 1045/1083 [===========================>..] - ETA: 0s - loss: 0.0044 - accuracy: 1060/1083 [============================>.] - ETA: 0s - loss: 0.0044 - accuracy: 1075/1083 [============================>.] - ETA: 0s - loss: 0.0044 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0044 - accuracy: 0.9984
Epoch 20/20
   1/1083 [..............................] - ETA: 4s - loss: 0.0036 - accuracy:   15/1083 [..............................] - ETA: 4s - loss: 0.0059 - accuracy:   28/1083 [..............................] - ETA: 4s - loss: 0.0040 - accuracy:   41/1083 [>.............................] - ETA: 4s - loss: 0.0053 - accuracy:   54/1083 [>.............................] - ETA: 4s - loss: 0.0057 - accuracy:   70/1083 [>.............................] - ETA: 3s - loss: 0.0059 - accuracy:   84/1083 [=>............................] - ETA: 3s - loss: 0.0058 - accuracy:   99/1083 [=>............................] - ETA: 3s - loss: 0.0052 - accuracy:  114/1083 [==>...........................] - ETA: 3s - loss: 0.0052 - accuracy:  127/1083 [==>...........................] - ETA: 3s - loss: 0.0051 - accuracy:  139/1083 [==>...........................] - ETA: 3s - loss: 0.0050 - accuracy:  153/1083 [===>..........................] - ETA: 3s - loss: 0.0047 - accuracy:  167/1083 [===>..........................] - ETA: 3s - loss: 0.0045 - accuracy:  179/1083 [===>..........................] - ETA: 3s - loss: 0.0046 - accuracy:  191/1083 [====>.........................] - ETA: 3s - loss: 0.0048 - accuracy:  204/1083 [====>.........................] - ETA: 3s - loss: 0.0051 - accuracy:  218/1083 [=====>........................] - ETA: 3s - loss: 0.0049 - accuracy:  233/1083 [=====>........................] - ETA: 3s - loss: 0.0047 - accuracy:  248/1083 [=====>........................] - ETA: 3s - loss: 0.0048 - accuracy:  264/1083 [======>.......................] - ETA: 3s - loss: 0.0050 - accuracy:  278/1083 [======>.......................] - ETA: 3s - loss: 0.0051 - accuracy:  293/1083 [=======>......................] - ETA: 2s - loss: 0.0052 - accuracy:  307/1083 [=======>......................] - ETA: 2s - loss: 0.0050 - accuracy:  322/1083 [=======>......................] - ETA: 2s - loss: 0.0049 - accuracy:  334/1083 [========>.....................] - ETA: 2s - loss: 0.0049 - accuracy:  347/1083 [========>.....................] - ETA: 2s - loss: 0.0049 - accuracy:  359/1083 [========>.....................] - ETA: 2s - loss: 0.0048 - accuracy:  372/1083 [=========>....................] - ETA: 2s - loss: 0.0047 - accuracy:  386/1083 [=========>....................] - ETA: 2s - loss: 0.0046 - accuracy:  400/1083 [==========>...................] - ETA: 2s - loss: 0.0046 - accuracy:  411/1083 [==========>...................] - ETA: 2s - loss: 0.0045 - accuracy:  425/1083 [==========>...................] - ETA: 2s - loss: 0.0045 - accuracy:  439/1083 [===========>..................] - ETA: 2s - loss: 0.0045 - accuracy:  453/1083 [===========>..................] - ETA: 2s - loss: 0.0044 - accuracy:  467/1083 [===========>..................] - ETA: 2s - loss: 0.0044 - accuracy:  483/1083 [============>.................] - ETA: 2s - loss: 0.0044 - accuracy:  498/1083 [============>.................] - ETA: 2s - loss: 0.0043 - accuracy:  514/1083 [=============>................] - ETA: 2s - loss: 0.0042 - accuracy:  530/1083 [=============>................] - ETA: 2s - loss: 0.0042 - accuracy:  545/1083 [==============>...............] - ETA: 2s - loss: 0.0042 - accuracy:  561/1083 [==============>...............] - ETA: 1s - loss: 0.0042 - accuracy:  576/1083 [==============>...............] - ETA: 1s - loss: 0.0042 - accuracy:  591/1083 [===============>..............] - ETA: 1s - loss: 0.0042 - accuracy:  605/1083 [===============>..............] - ETA: 1s - loss: 0.0042 - accuracy:  619/1083 [================>.............] - ETA: 1s - loss: 0.0041 - accuracy:  631/1083 [================>.............] - ETA: 1s - loss: 0.0041 - accuracy:  644/1083 [================>.............] - ETA: 1s - loss: 0.0041 - accuracy:  657/1083 [=================>............] - ETA: 1s - loss: 0.0041 - accuracy:  670/1083 [=================>............] - ETA: 1s - loss: 0.0041 - accuracy:  684/1083 [=================>............] - ETA: 1s - loss: 0.0042 - accuracy:  698/1083 [==================>...........] - ETA: 1s - loss: 0.0042 - accuracy:  713/1083 [==================>...........] - ETA: 1s - loss: 0.0042 - accuracy:  724/1083 [===================>..........] - ETA: 1s - loss: 0.0042 - accuracy:  738/1083 [===================>..........] - ETA: 1s - loss: 0.0042 - accuracy:  751/1083 [===================>..........] - ETA: 1s - loss: 0.0041 - accuracy:  763/1083 [====================>.........] - ETA: 1s - loss: 0.0041 - accuracy:  776/1083 [====================>.........] - ETA: 1s - loss: 0.0041 - accuracy:  789/1083 [====================>.........] - ETA: 1s - loss: 0.0041 - accuracy:  802/1083 [=====================>........] - ETA: 1s - loss: 0.0041 - accuracy:  814/1083 [=====================>........] - ETA: 1s - loss: 0.0041 - accuracy:  826/1083 [=====================>........] - ETA: 0s - loss: 0.0041 - accuracy:  838/1083 [======================>.......] - ETA: 0s - loss: 0.0041 - accuracy:  851/1083 [======================>.......] - ETA: 0s - loss: 0.0040 - accuracy:  866/1083 [======================>.......] - ETA: 0s - loss: 0.0040 - accuracy:  881/1083 [=======================>......] - ETA: 0s - loss: 0.0040 - accuracy:  897/1083 [=======================>......] - ETA: 0s - loss: 0.0040 - accuracy:  912/1083 [========================>.....] - ETA: 0s - loss: 0.0041 - accuracy:  928/1083 [========================>.....] - ETA: 0s - loss: 0.0042 - accuracy:  943/1083 [=========================>....] - ETA: 0s - loss: 0.0042 - accuracy:  958/1083 [=========================>....] - ETA: 0s - loss: 0.0042 - accuracy:  973/1083 [=========================>....] - ETA: 0s - loss: 0.0042 - accuracy:  988/1083 [==========================>...] - ETA: 0s - loss: 0.0042 - accuracy: 1003/1083 [==========================>...] - ETA: 0s - loss: 0.0041 - accuracy: 1019/1083 [===========================>..] - ETA: 0s - loss: 0.0042 - accuracy: 1035/1083 [===========================>..] - ETA: 0s - loss: 0.0041 - accuracy: 1051/1083 [============================>.] - ETA: 0s - loss: 0.0042 - accuracy: 1067/1083 [============================>.] - ETA: 0s - loss: 0.0042 - accuracy: 1082/1083 [============================>.] - ETA: 0s - loss: 0.0042 - accuracy: 1083/1083 [==============================] - 4s 4ms/step - loss: 0.0042 - accuracy: 0.9984
  1/830 [..............................] - ETA: 1:33 - loss: 0.0585 - accuracy:  25/830 [..............................] - ETA: 1s - loss: 0.0983 - accuracy: 0. 53/830 [>.............................] - ETA: 1s - loss: 0.1087 - accuracy: 0. 81/830 [=>............................] - ETA: 1s - loss: 0.0959 - accuracy: 0.109/830 [==>...........................] - ETA: 1s - loss: 0.0939 - accuracy: 0.135/830 [===>..........................] - ETA: 1s - loss: 0.1021 - accuracy: 0.162/830 [====>.........................] - ETA: 1s - loss: 0.1010 - accuracy: 0.189/830 [=====>........................] - ETA: 1s - loss: 0.0975 - accuracy: 0.217/830 [======>.......................] - ETA: 1s - loss: 0.0987 - accuracy: 0.244/830 [=======>......................] - ETA: 1s - loss: 0.0966 - accuracy: 0.270/830 [========>.....................] - ETA: 1s - loss: 0.0952 - accuracy: 0.296/830 [=========>....................] - ETA: 1s - loss: 0.0945 - accuracy: 0.323/830 [==========>...................] - ETA: 0s - loss: 0.0945 - accuracy: 0.350/830 [===========>..................] - ETA: 0s - loss: 0.0967 - accuracy: 0.377/830 [============>.................] - ETA: 0s - loss: 0.0952 - accuracy: 0.405/830 [=============>................] - ETA: 0s - loss: 0.0950 - accuracy: 0.431/830 [==============>...............] - ETA: 0s - loss: 0.0953 - accuracy: 0.458/830 [===============>..............] - ETA: 0s - loss: 0.0976 - accuracy: 0.485/830 [================>.............] - ETA: 0s - loss: 0.0984 - accuracy: 0.511/830 [=================>............] - ETA: 0s - loss: 0.0980 - accuracy: 0.539/830 [==================>...........] - ETA: 0s - loss: 0.1020 - accuracy: 0.563/830 [===================>..........] - ETA: 0s - loss: 0.1016 - accuracy: 0.589/830 [====================>.........] - ETA: 0s - loss: 0.1038 - accuracy: 0.616/830 [=====================>........] - ETA: 0s - loss: 0.1044 - accuracy: 0.642/830 [======================>.......] - ETA: 0s - loss: 0.1035 - accuracy: 0.667/830 [=======================>......] - ETA: 0s - loss: 0.1038 - accuracy: 0.693/830 [========================>.....] - ETA: 0s - loss: 0.1044 - accuracy: 0.714/830 [========================>.....] - ETA: 0s - loss: 0.1038 - accuracy: 0.739/830 [=========================>....] - ETA: 0s - loss: 0.1029 - accuracy: 0.765/830 [==========================>...] - ETA: 0s - loss: 0.1038 - accuracy: 0.792/830 [===========================>..] - ETA: 0s - loss: 0.1040 - accuracy: 0.820/830 [============================>.] - ETA: 0s - loss: 0.1044 - accuracy: 0.830/830 [==============================] - 2s 2ms/step - loss: 0.1044 - accuracy: 0.9624

***************** Summary *****************
Trained float model accuracy:  0.962410569190979
Trained float model is saved in  ./keras_curve_cnn2_line.h5

  1. 2022年12月08日 00:43 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

自作の白線間走行用 CNN を Vitis-AI の Custom OP WorkFlow で実行する1

白線間走行用CNNをKerasで学習する”で学習した白線間走行用 CNN を Vitis-AI のカスタム OP ワークフローで動作させてみたいということで、今回は、修正した train_eval_line.py と quntize_curve_line.py を貼っておく。更に、train_curve_run_image、train_curve_run_label、test_curve_run_image、test_curve_run_label、学習用データとテスト・データを読み込む curve_dataset.py を Vitis-AI/tf2_custom_op_demo ディレクトリにコピーした。

(2022/11/11:追記) train_eval_line.py と quntize_curve_line.py を 12/11 に変更した。詳しくは、”自作の白線間走行用 CNN を Vitis-AI の Custom OP Flow で実行する5”を参照のこと。

Vitis-AI/tf2_custom_op_demo の tran_eval.py と quntize.py をコピーして名前を train_eval_line.py と quntize_curve_line.py に変更した。そして、train_eval_line.py と quntize_curve_line.py の内容を一部変更した。

train_eval_line.py を示す。

# Copyright 2019 Xilinx Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# train_eval_line.py
# 2022/12/05 : modified by marsee
# 2022/12/08 : modified by marsee

import os, sys
import numpy as np
import tensorflow as tf
import argparse

print(tf.__version__)

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

from curve_dataset import load_mnist
from tensorflow.keras import utils as np_utils

parser = argparse.ArgumentParser(description='tensorflow 2 custom op example.')
parser.add_argument('--eval_only', type=bool, default=False, help='if only evaluate model')
parser.add_argument('--quant', type=bool, default=False, help='if evluate quantized model')

args = parser.parse_args()


class Mylayer(tf.keras.layers.Layer):
  def __init__(self, name="custom_layer", **kwargs):
    super().__init__(name=name, **kwargs)
    self.prelu = tf.keras.layers.PReLU()

  def call(self, inputs, training=None, mask=None):
    x = self.prelu(inputs)
    return x

custom_objects = {"Mylayer": Mylayer}

def build_model():
  inputs = tf.keras.Input((10, 56, 1))
  x = tf.keras.layers.Conv2D(2, (5, 5), activation='relu')(inputs)

  x = tf.keras.layers.MaxPooling2D((2, 2), (2, 2))(x)

  my_model = Mylayer()
  x = my_model(x)

  x = tf.keras.layers.Flatten()(x)
  x = tf.keras.layers.Dense(100, activation='relu')(x)
  x = tf.keras.layers.Dense(3, activation='softmax')(x)

  model = tf.keras.Model(inputs=inputs, outputs=x)
  return model

def main():
  #################################
  ###### build dataset
  #################################
  (x_train, y_train), (x_test, y_test) = load_mnist(normalize=False, flatten=False)
  trainzip = list(zip(y_train, x_train))
  np.random.shuffle(trainzip)
  y_train, x_train = zip(*trainzip)
  x_train = np.asarray(x_train)
  y_train = np.asarray(y_train)
  x_train = np.transpose(x_train,(0,2,3,1))

  testzip = list(zip(y_test, x_test))
  np.random.shuffle(testzip)
  y_test, x_test = zip(*testzip)
  x_test = np.asarray(x_test)
  y_test = np.asarray(y_test)
  x_test = np.transpose(x_test,(0,2,3,1))

  x_train = x_train.astype('float32')
  x_test = x_test.astype('float32')
  x_train /= 255
  x_test /= 255

  y_train = y_train.astype('int32')
  y_test = y_test.astype('int32')
  y_train = np_utils.to_categorical(y_train, 3)
  y_test =  np_utils.to_categorical(y_test, 3)

  #################################
  ##### evaluate model
  #################################
  if args.eval_only:
    if args.quant:
      from tensorflow_model_optimization.quantization.keras import vitis_quantize
      # quantized_model = tf.keras.models.load_model("./quantized/quantized.h5",
      #         custom_objects=custom_objects)
      with vitis_quantize.quantize_scope():
        quantized_model = tf.keras.models.load_model("./quantized/quantized_curve_line.h5",
                custom_objects=custom_objects)
        quantized_model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
        eval_results = quantized_model.evaluate(x_test, y_test)
        print("\n***************** Summary *****************")
        print("Quantized model accuracy: ", eval_results[1])
      return
    loaded_model = tf.keras.models.load_model("./keras_curve_cnn2_line.h5",
            custom_objects=custom_objects)
    eval_results = loaded_model.evaluate(x_test, y_test)
    print("\n***************** Summary *****************")
    print("Float model accuracy: ", eval_results[1])
    return
  #################################
  ##### build model
  #################################
  model = build_model()
  model.summary()
  #################################
  ##### compile train
  #################################
  model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
  model.fit(x_train, y_train, epochs=20, shuffle=True)
  eval_results = model.evaluate(x_test, y_test)
  print("\n***************** Summary *****************")
  print("Trained float model accuracy: ", eval_results[1])
  save_path = "./keras_curve_cnn2_line.h5"
  print("Trained float model is saved in ", save_path)
  model.save(save_path)

if __name__ == '__main__':
  main()


quntize_curve_line.py を示す。

# Copyright 2019 Xilinx Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# quantize_curve_line.py
# 2022/12/05 : modified by marsee

import os, sys
import numpy as np
import tensorflow as tf

from curve_dataset import load_mnist
from train_eval_line import custom_objects

print(tf.__version__)
os.environ["CUDA_VISIBLE_DEVICES"] = "0"


def main():
  #################################
  ###### build dataset
  #################################
  (x_train, y_train), (x_test, y_test) = load_mnist(normalize=False, flatten=False)
  
  testzip = list(zip(y_test, x_test))
  np.random.shuffle(testzip)
  y_test, x_test = zip(*testzip)
  x_test = np.asarray(x_test)
  y_test = np.asarray(y_test)
  x_test = np.transpose(x_test,(0,2,3,1))
  x_test = x_test.astype('float32')
  x_test /= 255

  #################################
  ##### quantize model
  #################################
  loaded_model = tf.keras.models.load_model("./keras_curve_cnn2_line.h5",
          custom_objects=custom_objects)
  loaded_model.summary()
  from tensorflow_model_optimization.quantization.keras import vitis_quantize
  # do quantization
  calib_dataset = x_test
  quant_model = vitis_quantize.VitisQuantizer(loaded_model, custom_objects=custom_objects).quantize_model(
      calib_dataset=calib_dataset,
      add_shape_info=True)
  # quant_model.summary()
  q_save_path = os.path.join('./quantized', 'quantized_curve_line.h5')
  quant_model.save(q_save_path)
  print("\n***************** Summary *****************")
  print("Quantized model is saved in ", q_save_path)

if __name__ == '__main__':
  main()


学習用データ・セットをコピーした。
カーブ、直線用白線間走行用畳み込みニューラルネットワーク5(トレーニング用データの生成)”で生成した train_curve_run_image と train_curve_run_label を Vitis-AI/tf2_custom_op_demo ディレクトリにコピーした。
カーブ、直線用白線間走行用畳み込みニューラルネットワーク7(テスト用データの作成)”で生成した test_curve_run_image のテスト用画像ファイルと test_curve_run_label のテスト用ラベル・ファイルを Vitis-AI/tf2_custom_op_demo ディレクトリにコピーした。

これらの学習用データとテスト・データを読み込む curve_dataset.py を貼っておく。

# curve_dataset.py
# 2017/12/18 白線追従走行用CNNに変更 by marsee
# 元になったコードは、https://github.com/oreilly-japan/deep-learning-from-scratch の mnist.py です
# 改変したコードもMITライセンスとします。 2017/12/18 by marsee

# coding: utf-8
try:
    import urllib.request
except ImportError:
    raise ImportError('You should use Python 3.x')
import os.path
import gzip
import pickle
import os
import numpy as np


key_file = {
    'train_img':'train_curve_run_image',
    'train_label':'train_curve_run_label',
    'test_img':'test_curve_run_image',
    'test_label':'test_curve_run_label'
}

dataset_dir = os.path.dirname(os.path.abspath(__file__))
save_file = dataset_dir + "/mnist.pkl"

train_num = 34650
test_num = 26550
img_dim = (1, 10, 56)
img_size = 560


def _load_label(file_name):
    file_path = dataset_dir + "/" + file_name
    
    print("Converting " + file_name + " to NumPy Array ...")
    with open(file_path, 'rb') as f:
            labels = np.frombuffer(f.read(), np.uint8, offset=8)
    print("Done")
    
    return labels

def _load_img(file_name):
    file_path = dataset_dir + "/" + file_name
    
    print("Converting " + file_name + " to NumPy Array ...")    
    with open(file_path, 'rb') as f:
            data = np.frombuffer(f.read(), np.uint8, offset=16)
    data = data.reshape(-1, img_size)
    print("Done")
    
    return data
    
def _convert_numpy():
    dataset = {}
    dataset['train_img'] =  _load_img(key_file['train_img'])
    dataset['train_label'] = _load_label(key_file['train_label'])    
    dataset['test_img'] = _load_img(key_file['test_img'])
    dataset['test_label'] = _load_label(key_file['test_label'])
    
    return dataset

def init_mnist():
    dataset = _convert_numpy()
    print("Creating pickle file ...")
    with open(save_file, 'wb') as f:
        pickle.dump(dataset, f, -1)
    print("Done!")

def _change_one_hot_label(X):
    T = np.zeros((X.size, 3))
    for idx, row in enumerate(T):
        row[X[idx]] = 1
        
    return T
    

def load_mnist(normalize=True, flatten=True, one_hot_label=False):
    """MNISTデータセットの読み込み
    
    Parameters
    ----------
    normalize : 画像のピクセル値を0.0~1.0に正規化する
    one_hot_label : 
        one_hot_labelがTrueの場合、ラベルはone-hot配列として返す
        one-hot配列とは、たとえば[0,0,1,0,0,0,0,0,0,0]のような配列
    flatten : 画像を一次元配列に平にするかどうか 
    
    Returns
    -------
    (訓練画像, 訓練ラベル), (テスト画像, テストラベル)
    """
    if not os.path.exists(save_file):
        init_mnist()
        
    with open(save_file, 'rb') as f:
        dataset = pickle.load(f)
    
    if normalize:
        for key in ('train_img', 'test_img'):
            dataset[key] = dataset[key].astype(np.float32)
            dataset[key] /= 255.0
            
    if one_hot_label:
        dataset['train_label'] = _change_one_hot_label(dataset['train_label'])
        dataset['test_label'] = _change_one_hot_label(dataset['test_label'])
    
    if not flatten:
         for key in ('train_img', 'test_img'):
            dataset[key] = dataset[key].reshape(-1, 1, 10, 56)

    return (dataset['train_img'], dataset['train_label']), (dataset['test_img'], dataset['test_label']) 


if __name__ == '__main__':
    init_mnist()


Custom_OP_Workflow_37_221207.png
  1. 2022年12月07日 04:23 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートを使って、TensorFlow + Keras で学習した MNIST を XMDEL にする2

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートを使って、TensorFlow + Keras で学習した MNIST を XMDEL にする”の続き。

前回は、私が自分で学習した MNIST の h5 ファイルを使用して、XMODEL を作成した。今回は、その XMODEL を使用して、KV260 の Petalinux 2022.1 で実際に MNIST を動作させてみよう。

KV260 の Petalinux 2022.1 の設定は、”Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる3”で全てやってあるので、XMODEL を転送して、実行してみれば良いはずだ。

FileZilla で tf2_minist_cnn5.xmodel を KV260 の Petalinux 2022.1 にアップロードした。
Custom_OP_Workflow_33_221206.png

カスタム OP デモを実行する。
cd ~/kv260_median/dpu
sudo mkdir -p /run/media/mmcblk0p1/
sudo cp dpu.xclbin /run/media/mmcblk0p1/
sudo xmutil unloadapp
sudo xmutil loadapp dpuprj
cd ~/tensorflow2_example/deployment/cpp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_mnist_cnn5.xmodel ~/tensorflow2_example/sample.jpg

Custom_OP_Workflow_34_221206.png
Custom_OP_Workflow_35_221206.png

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_mnist_cnn5.xmodel ~/tensorflow2_example/sample.jpg
model_file: /home/petalinux/tensorflow2_example/tf2_mnist_cnn5.xmodel
image_path: /home/petalinux/tensorflow2_example/sample.jpg
image file /home/petalinux/tensorflow2_example/sample.jpg result:
 score[0]   =  0           
 score[1]   =  0           
 score[2]   =  nan         
 score[3]   =  nan         
 score[4]   =  0           
 score[5]   =  0           
 score[6]   =  0           
 score[7]   =  nan         
 score[8]   =  0           
 score[9]   =  nan         


数字の 7 の画像を認識できなかった。やはり、層の構造が違っているネットワークを無理やり XMODEL にしたのが原因なのか?

最後の層を softmax にしていないので、nan が出ているのかも知れない?そうなると score[7] = nan だし、うまく行っている可能性もあるのか?
  1. 2022年12月06日 04:04 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる3

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる2”の続き。

Vitis-AI 2.5 のカスタム OP ワークフローをやってみようということで、前回は、量子化を行ってコンパイルして XMODL を生成した。今回は、生成された XMODEL と sample.jpg を KV260 に送って、動作させてみたがエラーになってしまった。

Vitis-AI/examples/Custom_OP_Demo/tensorflow2_example ディレクトリを KV260 の Petalinux 2022.1 の /home/petalinux ディレクトリにコピーする。
Custom_OP_Workflow_25_221205.png

KV260 の Petalinux 2022.1 でカスタム OP を登録する。
cd ~/tensorflow2_example/op_registration/cpp
bash op_registration.sh

Custom_OP_Workflow_31_221205.png

sample.jpg をダウンロードする。
Custom_OP_Workflow_26_221205.png

XMODL と sample.jpg を KV260 の Petalinux 2022.1 の ~/tensorflow2_example ディレクトリにコピーする。
Custom_OP_Workflow_27_221205.png

KV260 の Petalinux 2022.1 上で tf2_custom_op_graph_runner.cpp をコンパイルする。
cd ~/tensorflow2_example/deployment/cpp
bash build.sh

tf2_custom_op_graph_runner が生成された。
Custom_OP_Workflow_28_221205.png

カスタム OP デモを実行する。
cd ~/kv260_median/dpu
sudo mkdir -p /run/media/mmcblk0p1/
sudo cp dpu.xclbin /run/media/mmcblk0p1/
sudo xmutil unloadapp
sudo xmutil loadapp dpuprj
cd ~/tensorflow2_example/deployment/cpp
./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/sample.jpg

うまく行って、7 と認識されている。
Custom_OP_Workflow_29_221205.png
Custom_OP_Workflow_32_221205.png

xilinx-k26-starterkit-20221:~/tensorflow2_example/deployment/cpp$ ./tf2_custom_op_graph_runner ~/tensorflow2_example/tf2_custom_op.xmodel ~/tensorflow2_example/sample.jpg
model_file: /home/petalinux/tensorflow2_example/tf2_custom_op.xmodel
image_path: /home/petalinux/tensorflow2_example/sample.jpg
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1204 12:08:48.427207  1485 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
image file /home/petalinux/tensorflow2_example/sample.jpg result:
    score[0]   =  0           
    score[1]   =  0           
    score[2]   =  0           
    score[3]   =  0           
    score[4]   =  0           
    score[5]   =  0           
    score[6]   =  0           
    score[7]   =  0.992188    
    score[8]   =  0           
    score[9]   =  0           

  1. 2022年12月05日 05:21 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートを使って、TensorFlow + Keras で学習した MNIST を XMDEL にする

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる2”の続き。

前回は、たぶん MNIST の量子化を行ってコンパイルして XMODL を生成した。今回は、私が自分で学習した MNIST の h5 ファイルを使用して、XMODEL を作成してみよう。

TensorFlow + Kerasを使ってみた3(以前使用したCNNを使った学習)”で学習した MNIST 用 CNN の h5 ファイルを使用する。
なお、Tensorflow のバージョンは 1.8.0 で、Keras のバージョンは 2.1.6 だった。

mnist_cnn5_model.h5 ファイルを Vitis-AI/tf2_custom_op_demo ディレクトリにコピーした。
Custom_OP_Workflow_16_221204.png

量子化は quantize.py で実行されているので、quantize.py をコピーして quantize_mnist.py に名前を変更した。
quantize_mnist.py のハードコードされているモデルの名前と量子化して出力するファイル名を変更した。
Custom_OP_Workflow_17_221204.png

quantize_mnist.py を実行した。
python quantize_mnist.py
Custom_OP_Workflow_18_221204.png
Custom_OP_Workflow_19_221204.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > python quantize_mnist.py 
2022-11-29 00:49:09.449636: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:49:09.449656: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2.8.0
2.8.0
2022-11-29 00:49:11.139032: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:49:11.139049: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-11-29 00:49:11.139099: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:163] no NVIDIA GPU device is present: /dev/nvidia0 does not exist
2022-11-29 00:49:11.139418: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_1 (Conv2D)           (None, 24, 24, 5)         130       
                                                                 
 activation_1 (Activation)   (None, 24, 24, 5)         0         
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 12, 12, 5)        0         
 2D)                                                             
                                                                 
 flatten_1 (Flatten)         (None, 720)               0         
                                                                 
 dense_1 (Dense)             (None, 100)               72100     
                                                                 
 activation_2 (Activation)   (None, 100)               0         
                                                                 
 dense_2 (Dense)             (None, 10)                1010      
                                                                 
 activation_3 (Activation)   (None, 10)                0         
                                                                 
=================================================================
Total params: 73,240
Trainable params: 73,240
Non-trainable params: 0
_________________________________________________________________
[VAI INFO] Start CrossLayerEqualization...
10/10 [==============================] - 1s 56ms/step
[VAI INFO] CrossLayerEqualization Done.
[VAI INFO] Start Quantize Calibration...
313/313 [==============================] - 3s 6ms/step
[VAI INFO] Quantize Calibration Done.
[VAI INFO] Start Post-Quant Model Refinement...
[VAI INFO] Start Quantize Position Ajustment...
[VAI INFO] Quantize Position Ajustment Done.
[VAI INFO] Start Getting Shape Information...
[VAI INFO] Getting model layer shape information
[VAI INFO] Getting Shape Information Done.
[VAI INFO] Post-Quant Model Refninement Done.
[VAI INFO] Start Model Finalization...
[VAI INFO] Model Finalization Done.
[VAI INFO] Quantization Finished.
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.

***************** Summary *****************
Quantized model is saved in  ./quantized/quantized_mnist_cnn5.h5


./quantized/quantized_mnist_cnn5.h5 ファイルが出力された。

コンパイルを行った。
vai_c_tensorflow2 -m ./quantized/quantized_mnist_cnn5.h5 -a ../kv260_myarch.json -o ./ -n tf2_mnist_cnn5
Custom_OP_Workflow_20_221204.png
Custom_OP_Workflow_21_221204.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > vai_c_tensorflow2 -m ./quantized/quantized_mnist_cnn5.h5 -a ../kv260_myarch.json -o ./ -n tf2_mnist_cnn5
**************************************************
* VITIS_AI Compilation - Xilinx Inc.
**************************************************
[INFO] Namespace(batchsize=1, inputs_shape=None, layout='NHWC', model_files=['./quantized/quantized_mnist_cnn5.h5'], model_type='tensorflow2', named_inputs_shape=None, out_filename='/tmp/tf2_mnist_cnn5_0x101000017010406_org.xmodel', proto=None)
[INFO] tensorflow2 model: /workspace/tf2_custom_op_demo/quantized/quantized_mnist_cnn5.h5
[INFO] keras version: 2.8.0
[INFO] Tensorflow Keras model type: sequential
/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib/python3.7/site-packages/xnnc/translator/tensorflow_translator.py:2537: H5pyDeprecationWarning: dataset.value has been deprecated. Use dataset[()] instead.
  layer['config']['shape'] = h5f['optimizer_weights'][name+':0'].value.tolist()
[INFO] parse raw model     :100%|█| 10/10 [00:00<00:00, 12139.81it/s]           
[INFO] infer shape (NHWC)  :100%|█| 18/18 [00:00<00:00, 1657.50it/s]            
[INFO] perform level-0 opt :100%|█| 2/2 [00:00<00:00, 476.87it/s]               
[INFO] perform level-1 opt :100%|█| 2/2 [00:00<00:00, 1887.63it/s]              
[INFO] generate xmodel     :100%|█| 18/18 [00:00<00:00, 1958.13it/s]            
[INFO] dump xmodel: /tmp/tf2_mnist_cnn5_0x101000017010406_org.xmodel
[UNILOG][INFO] Compile mode: dpu
[UNILOG][INFO] Debug mode: function
[UNILOG][INFO] Target architecture: DPUCZDX8G_ISA1_B3136_0101000017010406
[UNILOG][INFO] Graph name: sequential, with op num: 26
[UNILOG][INFO] Begin to compile...
[UNILOG][INFO] Total device subgraph number 3, DPU subgraph number 1
[UNILOG][INFO] Compile done.
[UNILOG][INFO] The meta json is saved to "/workspace/tf2_custom_op_demo/./meta.json"
[UNILOG][INFO] The compiled xmodel is saved to "/workspace/tf2_custom_op_demo/.//tf2_mnist_cnn5.xmodel"
[UNILOG][INFO] The compiled xmodel's md5sum is 2ef83615a04046e55ee9e1fcecdff9e7, and has been saved to "/workspace/tf2_custom_op_demo/./md5sum.txt"



tf2_minist_cnn5.xmodel が生成された。
Custom_OP_Workflow_22_221204.png

netronで XMODEL の構成を見た。
Custom_OP_Workflow_23_221204.png
Custom OP Workflow と同じ MNIST なので、うまく行ったようだ。
  1. 2022年12月04日 04:30 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる2

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる1”の続き。

Vitis-AI 2.5 のカスタム OP ワークフローをやってみようということで、前回は、tf2_custom_op_demo.tar.gz をダウンロードして解凍し、1_run_train.sh を実行して学習した。今回は、量子化を行ってコンパイルして XMODL を生成した。

量子化を行った。
bash 3_run_quantize.sh
Custom_OP_Workflow_9_221202.png
Custom_OP_Workflow_10_221202.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > bash 3_run_quantize.sh
2022-11-29 00:30:07.215340: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:30:07.215358: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2.8.0
2.8.0
2022-11-29 00:30:08.950130: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:30:08.950152: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-11-29 00:30:08.950183: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:163] no NVIDIA GPU device is present: /dev/nvidia0 does not exist
2022-11-29 00:30:08.950373: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 28, 28, 1)]       0         
                                                                 
 conv2d (Conv2D)             (None, 22, 22, 32)        1600      
                                                                 
 batch_normalization (BatchN  (None, 22, 22, 32)       128       
 ormalization)                                                   
                                                                 
 conv2d_1 (Conv2D)           (None, 16, 16, 32)        50208     
                                                                 
 batch_normalization_1 (Batc  (None, 16, 16, 32)       128       
 hNormalization)                                                 
                                                                 
 max_pooling2d (MaxPooling2D  (None, 8, 8, 32)         0         
 )                                                               
                                                                 
 conv2d_2 (Conv2D)           (None, 4, 4, 64)          51264     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 2, 2, 64)         0         
 2D)                                                             
                                                                 
 custom_layer (Mylayer)      (None, 2, 2, 64)          256       
                                                                 
 flatten (Flatten)           (None, 256)               0         
                                                                 
 dense (Dense)               (None, 10)                2570      
                                                                 
=================================================================
Total params: 106,154
Trainable params: 106,026
Non-trainable params: 128
_________________________________________________________________
[VAI INFO] Update custom_layer_type: ['Mylayer']
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Start CrossLayerEqualization...
 1/10 [==>...........................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 2/10 [=====>........................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 3/10 [========>.....................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 4/10 [===========>..................] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 5/10 [==============>...............] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 6/10 [=================>............] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 7/10 [====================>.........] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 8/10 [=======================>......] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
 9/10 [==========================>...] - ETA: 0s[VAI INFO] setting custom layer weights, layer name: custom_layer
10/10 [==============================] - 1s 84ms/step
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] CrossLayerEqualization Done.
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Layer custom_layer(<class 'train_eval.Mylayer'>) is not supported by DPU, it will not be quantized and may be mapped to run on CPU or other IPs. Please see User Guide for list of supported operations and APIs of vai_q_tensorflow2.
[VAI INFO] setting custom layer weights, layer name: custom_layer
[VAI INFO] Start Quantize Calibration...
313/313 [==============================] - 8s 19ms/step
[VAI INFO] Quantize Calibration Done.
[VAI INFO] Start Post-Quant Model Refinement...
[VAI INFO] Start Quantize Position Ajustment...
[VAI INFO] Quantize Position Ajustment Done.
[VAI INFO] Start Getting Shape Information...
[VAI INFO] Getting model layer shape information
[VAI INFO] Getting Shape Information Done.
[VAI INFO] Post-Quant Model Refninement Done.
[VAI INFO] Start Model Finalization...
[VAI INFO] Model Finalization Done.
[VAI INFO] Quantization Finished.
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.

***************** Summary *****************
Quantized model is saved in  ./quantized/quantized.h5


./quantized/quantized.h5 が生成された。

kv260_median アクセラレーション・プラットフォームに Vitis-AI の DPU を追加する8”で生成した kv260_myarch.json を Vitis-AI のホーム・ディレクトリにコピーした。

コンパイルを行う。
vai_c_tensorflow2 -m ./quantized/quantized.h5 -a ../kv260_myarch.json -o ./ -n tf2_custom_op
Custom_OP_Workflow_11_221203.png
Custom_OP_Workflow_12_221203.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > vai_c_tensorflow2 -m ./quantized/quantized.h5 -a ../kv260_myarch.json -o ./ -n tf2_custom_op
**************************************************
* VITIS_AI Compilation - Xilinx Inc.
**************************************************
[INFO] Namespace(batchsize=1, inputs_shape=None, layout='NHWC', model_files=['./quantized/quantized.h5'], model_type='tensorflow2', named_inputs_shape=None, out_filename='/tmp/tf2_custom_op_0x101000017010406_org.xmodel', proto=None)
[INFO] tensorflow2 model: /workspace/tf2_custom_op_demo/quantized/quantized.h5
[INFO] keras version: 2.8.0
[INFO] Tensorflow Keras model type: functional
/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib/python3.7/site-packages/xnnc/translator/tensorflow_translator.py:2537: H5pyDeprecationWarning: dataset.value has been deprecated. Use dataset[()] instead.
  layer['config']['shape'] = h5f['optimizer_weights'][name+':0'].value.tolist()
[INFO] parse raw model     :100%|█| 12/12 [00:00<00:00, 13443.28it/s]           
[INFO] infer shape (NHWC)  :100%|█| 22/22 [00:00<00:00, 23022.63it/s]           
[INFO] perform level-0 opt :100%|█| 2/2 [00:00<00:00, 658.34it/s]               
[INFO] perform level-1 opt :100%|█| 2/2 [00:00<00:00, 1920.91it/s]              
[INFO] infer shape (NHWC)  :100%|█| 24/24 [00:00<00:00, 34580.31it/s]           
[INFO] generate xmodel     :  0%| | 0/24 [00:00<?, ?it/s]                       WARNING: Logging before InitGoogleLogging() is written to STDERR
W1129 00:44:08.246577   190 tool_function.cpp:171] [UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
[INFO] generate xmodel     :100%|█| 24/24 [00:00<00:00, 4493.30it/s]            
[INFO] dump xmodel: /tmp/tf2_custom_op_0x101000017010406_org.xmodel
[UNILOG][WARNING] The operator named custom_layer, type: Mylayer, is not defined in XIR. XIR creates the definition of this operator automatically. You should specify the shape and the data_type of the output tensor of this operation by set_attr("shape", std::vector<int>) and set_attr("data_type", std::string)
[UNILOG][INFO] Compile mode: dpu
[UNILOG][INFO] Debug mode: function
[UNILOG][INFO] Target architecture: DPUCZDX8G_ISA1_B3136_0101000017010406
[UNILOG][INFO] Graph name: model, with op num: 38
[UNILOG][INFO] Begin to compile...
[UNILOG][INFO] Total device subgraph number 5, DPU subgraph number 2
[UNILOG][INFO] Compile done.
[UNILOG][INFO] The meta json is saved to "/workspace/tf2_custom_op_demo/./meta.json"
[UNILOG][INFO] The compiled xmodel is saved to "/workspace/tf2_custom_op_demo/.//tf2_custom_op.xmodel"
[UNILOG][INFO] The compiled xmodel's md5sum is b7bcab55b1965061ca5c14e9bcd008a5, and has been saved to "/workspace/tf2_custom_op_demo/./md5sum.txt"


tf2_custom_op.xmodel が生成された。
Custom_OP_Workflow_13_221203.png

netronで XMODEL の構成を見た。
Custom_OP_Workflow_14_221203.pngCustom_OP_Workflow_15_221203.png
  1. 2022年12月03日 09:07 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis-AI 2.5 の Custom OP Workflow のクイックスタートをやってみる1

Vitis-AI 2.5 の Custom OP Workflow のクリックスタートをやる前に Custom OP Workflow について見ていく。
Vitis-AI 2.5 の英語版の Custom OP Workflow と、日本語版のカスタム OP ワークフローについてのリンクを示す。

Vitis-AI 日本語版のカスタム OP ワークフローから”図 カスタム OP ワークフロー”を引用する。
Custom_OP_Workflow_1_221202.png

Vitis-AI 日本語版のカスタム OP ワークフローから”図 カスタム OP ワークフロー”の説明文を引用する。

このワークフローの手順は次のとおりです。
 1. OP を XIR にとって未知のカスタム OP として定義し、モデルを量子化します。
 2. 量子化済みモデルをコンパイルします。
 3. カスタム OP を登録して実装します。
 4. graph_runner API を使用してモデルを運用します。
手順 3 では、カスタム OP の実装および登録用に C++ と Python の両方がサポートされます。Vitis AI ライブラリでサポートされる一般的な OP は 50 以上あります。一般的な OP のソース コードは、https://github.com/Xilinx/Vitis-AI/tree/master/src/Vitis-AI-Library/cpu_task/ops にあります。


この手順をクイックスタートで確認してみよう。
まずは、Vitis-AI 2.5 の ディレクトリに移動して Docker を起動する。
cd <Vitis-AI ディレクトリ>
./docker_run.sh xilinx/vitis-ai-cpu:2.5

Custom_OP_Workflow_2_221202.png
Custom_OP_Workflow_3_221202.png

tf2_custom_op_demo.tar.gz をダウンロードする。
wget https://www.xilinx.com/bin/public/openDownload?filename=tf2_custom_op_demo.tar.gz -O tf2_custom_op_demo.tar.gz
Custom_OP_Workflow_4_221202.png

tf2_custom_op_demo.tar.gz を解凍して、tf2_custom_op_demo に移動して、vitis-ai-tensorflow2 を conda activate する。
tar -xzvf tf2_custom_op_demo.tar.gz
cd tf2_custom_op_demo
conda activate vitis-ai-tensorflow2

Custom_OP_Workflow_5_221202.png

1_run_train.sh を実行して学習する。
bash 1_run_train.sh
Custom_OP_Workflow_6_221202.png
Custom_OP_Workflow_7_221202.png

(vitis-ai-tensorflow2) Vitis-AI /workspace/tf2_custom_op_demo > bash 1_run_train.sh
2022-11-29 00:23:46.284602: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:23:46.284672: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2.8.0
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 1s 0us/step
11501568/11490434 [==============================] - 1s 0us/step
2022-11-29 00:24:06.121607: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu
2022-11-29 00:24:06.121670: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-11-29 00:24:06.125895: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:163] no NVIDIA GPU device is present: /dev/nvidia0 does not exist
2022-11-29 00:24:06.133826: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 28, 28, 1)]       0         
                                                                 
 conv2d (Conv2D)             (None, 22, 22, 32)        1600      
                                                                 
 batch_normalization (BatchN  (None, 22, 22, 32)       128       
 ormalization)                                                   
                                                                 
 conv2d_1 (Conv2D)           (None, 16, 16, 32)        50208     
                                                                 
 batch_normalization_1 (Batc  (None, 16, 16, 32)       128       
 hNormalization)                                                 
                                                                 
 max_pooling2d (MaxPooling2D  (None, 8, 8, 32)         0         
 )                                                               
                                                                 
 conv2d_2 (Conv2D)           (None, 4, 4, 64)          51264     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 2, 2, 64)         0         
 2D)                                                             
                                                                 
 custom_layer (Mylayer)      (None, 2, 2, 64)          256       
                                                                 
 flatten (Flatten)           (None, 256)               0         
                                                                 
 dense (Dense)               (None, 10)                2570      
                                                                 
=================================================================
Total params: 106,154
Trainable params: 106,026
Non-trainable params: 128
_________________________________________________________________
Epoch 1/10
 1/32 [..............................] - ETA: 1:01 - loss: 1.0781 - accuracy: 0. 3/32 [=>............................] - ETA: 1s - loss: 0.6279 - accuracy: 0.21 5/32 [===>..........................] - ETA: 1s - loss: 0.4962 - accuracy: 0.26 7/32 [=====>........................] - ETA: 0s - loss: 0.4312 - accuracy: 0.31 9/32 [=======>......................] - ETA: 0s - loss: 0.3897 - accuracy: 0.3311/32 [=========>....................] - ETA: 0s - loss: 0.3583 - accuracy: 0.3713/32 [===========>..................] - ETA: 0s - loss: 0.3323 - accuracy: 0.4115/32 [=============>................] - ETA: 0s - loss: 0.3097 - accuracy: 0.4517/32 [==============>...............] - ETA: 0s - loss: 0.2956 - accuracy: 0.4819/32 [================>.............] - ETA: 0s - loss: 0.2765 - accuracy: 0.5221/32 [==================>...........] - ETA: 0s - loss: 0.2634 - accuracy: 0.5523/32 [====================>.........] - ETA: 0s - loss: 0.2572 - accuracy: 0.5525/32 [======================>.......] - ETA: 0s - loss: 0.2477 - accuracy: 0.5727/32 [========================>.....] - ETA: 0s - loss: 0.2428 - accuracy: 0.5829/32 [==========================>...] - ETA: 0s - loss: 0.2328 - accuracy: 0.6031/32 [============================>.] - ETA: 0s - loss: 0.2252 - accuracy: 0.6132/32 [==============================] - 3s 35ms/step - loss: 0.2249 - accuracy: 0.6190
Epoch 2/10
 1/32 [..............................] - ETA: 1s - loss: 0.1315 - accuracy: 0.84 3/32 [=>............................] - ETA: 1s - loss: 0.1153 - accuracy: 0.84 5/32 [===>..........................] - ETA: 0s - loss: 0.1036 - accuracy: 0.85 7/32 [=====>........................] - ETA: 0s - loss: 0.1060 - accuracy: 0.85 9/32 [=======>......................] - ETA: 0s - loss: 0.1018 - accuracy: 0.8511/32 [=========>....................] - ETA: 0s - loss: 0.1005 - accuracy: 0.8513/32 [===========>..................] - ETA: 0s - loss: 0.0948 - accuracy: 0.8715/32 [=============>................] - ETA: 0s - loss: 0.0947 - accuracy: 0.8617/32 [==============>...............] - ETA: 0s - loss: 0.0931 - accuracy: 0.8719/32 [================>.............] - ETA: 0s - loss: 0.0909 - accuracy: 0.8721/32 [==================>...........] - ETA: 0s - loss: 0.0925 - accuracy: 0.8723/32 [====================>.........] - ETA: 0s - loss: 0.0907 - accuracy: 0.8725/32 [======================>.......] - ETA: 0s - loss: 0.0910 - accuracy: 0.8727/32 [========================>.....] - ETA: 0s - loss: 0.0919 - accuracy: 0.8729/32 [==========================>...] - ETA: 0s - loss: 0.0911 - accuracy: 0.8731/32 [============================>.] - ETA: 0s - loss: 0.0889 - accuracy: 0.8732/32 [==============================] - 1s 35ms/step - loss: 0.0889 - accuracy: 0.8760
Epoch 3/10
 1/32 [..............................] - ETA: 1s - loss: 0.0707 - accuracy: 0.93 3/32 [=>............................] - ETA: 0s - loss: 0.0797 - accuracy: 0.88 5/32 [===>..........................] - ETA: 0s - loss: 0.0752 - accuracy: 0.90 7/32 [=====>........................] - ETA: 0s - loss: 0.0721 - accuracy: 0.90 9/32 [=======>......................] - ETA: 0s - loss: 0.0679 - accuracy: 0.9111/32 [=========>....................] - ETA: 0s - loss: 0.0677 - accuracy: 0.9013/32 [===========>..................] - ETA: 0s - loss: 0.0663 - accuracy: 0.9115/32 [=============>................] - ETA: 0s - loss: 0.0669 - accuracy: 0.9117/32 [==============>...............] - ETA: 0s - loss: 0.0650 - accuracy: 0.9219/32 [================>.............] - ETA: 0s - loss: 0.0634 - accuracy: 0.9221/32 [==================>...........] - ETA: 0s - loss: 0.0637 - accuracy: 0.9223/32 [====================>.........] - ETA: 0s - loss: 0.0635 - accuracy: 0.9225/32 [======================>.......] - ETA: 0s - loss: 0.0634 - accuracy: 0.9227/32 [========================>.....] - ETA: 0s - loss: 0.0635 - accuracy: 0.9229/32 [==========================>...] - ETA: 0s - loss: 0.0620 - accuracy: 0.9231/32 [============================>.] - ETA: 0s - loss: 0.0623 - accuracy: 0.9232/32 [==============================] - 1s 35ms/step - loss: 0.0625 - accuracy: 0.9280
Epoch 4/10
 1/32 [..............................] - ETA: 1s - loss: 0.0618 - accuracy: 0.90 3/32 [=>............................] - ETA: 1s - loss: 0.0520 - accuracy: 0.93 5/32 [===>..........................] - ETA: 0s - loss: 0.0512 - accuracy: 0.93 7/32 [=====>........................] - ETA: 0s - loss: 0.0547 - accuracy: 0.93 9/32 [=======>......................] - ETA: 0s - loss: 0.0533 - accuracy: 0.9311/32 [=========>....................] - ETA: 0s - loss: 0.0514 - accuracy: 0.9313/32 [===========>..................] - ETA: 0s - loss: 0.0514 - accuracy: 0.9315/32 [=============>................] - ETA: 0s - loss: 0.0506 - accuracy: 0.9417/32 [==============>...............] - ETA: 0s - loss: 0.0512 - accuracy: 0.9419/32 [================>.............] - ETA: 0s - loss: 0.0511 - accuracy: 0.9421/32 [==================>...........] - ETA: 0s - loss: 0.0512 - accuracy: 0.9323/32 [====================>.........] - ETA: 0s - loss: 0.0504 - accuracy: 0.9325/32 [======================>.......] - ETA: 0s - loss: 0.0507 - accuracy: 0.9327/32 [========================>.....] - ETA: 0s - loss: 0.0501 - accuracy: 0.9329/32 [==========================>...] - ETA: 0s - loss: 0.0499 - accuracy: 0.9331/32 [============================>.] - ETA: 0s - loss: 0.0501 - accuracy: 0.9332/32 [==============================] - 1s 35ms/step - loss: 0.0501 - accuracy: 0.9400
Epoch 5/10
 1/32 [..............................] - ETA: 1s - loss: 0.0497 - accuracy: 0.93 3/32 [=>............................] - ETA: 1s - loss: 0.0456 - accuracy: 0.92 5/32 [===>..........................] - ETA: 0s - loss: 0.0398 - accuracy: 0.95 7/32 [=====>........................] - ETA: 0s - loss: 0.0381 - accuracy: 0.95 9/32 [=======>......................] - ETA: 0s - loss: 0.0357 - accuracy: 0.9511/32 [=========>....................] - ETA: 0s - loss: 0.0346 - accuracy: 0.9613/32 [===========>..................] - ETA: 0s - loss: 0.0351 - accuracy: 0.9615/32 [=============>................] - ETA: 0s - loss: 0.0355 - accuracy: 0.9617/32 [==============>...............] - ETA: 0s - loss: 0.0355 - accuracy: 0.9619/32 [================>.............] - ETA: 0s - loss: 0.0364 - accuracy: 0.9621/32 [==================>...........] - ETA: 0s - loss: 0.0392 - accuracy: 0.9523/32 [====================>.........] - ETA: 0s - loss: 0.0390 - accuracy: 0.9625/32 [======================>.......] - ETA: 0s - loss: 0.0412 - accuracy: 0.9527/32 [========================>.....] - ETA: 0s - loss: 0.0409 - accuracy: 0.9529/32 [==========================>...] - ETA: 0s - loss: 0.0403 - accuracy: 0.9531/32 [============================>.] - ETA: 0s - loss: 0.0400 - accuracy: 0.9532/32 [==============================] - 1s 35ms/step - loss: 0.0398 - accuracy: 0.9570
Epoch 6/10
 1/32 [..............................] - ETA: 1s - loss: 0.0359 - accuracy: 0.93 3/32 [=>............................] - ETA: 1s - loss: 0.0360 - accuracy: 0.93 5/32 [===>..........................] - ETA: 0s - loss: 0.0337 - accuracy: 0.95 7/32 [=====>........................] - ETA: 0s - loss: 0.0311 - accuracy: 0.96 9/32 [=======>......................] - ETA: 0s - loss: 0.0302 - accuracy: 0.9611/32 [=========>....................] - ETA: 0s - loss: 0.0292 - accuracy: 0.9613/32 [===========>..................] - ETA: 0s - loss: 0.0302 - accuracy: 0.9615/32 [=============>................] - ETA: 0s - loss: 0.0288 - accuracy: 0.9617/32 [==============>...............] - ETA: 0s - loss: 0.0283 - accuracy: 0.9619/32 [================>.............] - ETA: 0s - loss: 0.0275 - accuracy: 0.9721/32 [==================>...........] - ETA: 0s - loss: 0.0294 - accuracy: 0.9623/32 [====================>.........] - ETA: 0s - loss: 0.0306 - accuracy: 0.9625/32 [======================>.......] - ETA: 0s - loss: 0.0306 - accuracy: 0.9627/32 [========================>.....] - ETA: 0s - loss: 0.0311 - accuracy: 0.9629/32 [==========================>...] - ETA: 0s - loss: 0.0307 - accuracy: 0.9631/32 [============================>.] - ETA: 0s - loss: 0.0309 - accuracy: 0.9632/32 [==============================] - 1s 35ms/step - loss: 0.0308 - accuracy: 0.9700
Epoch 7/10
 1/32 [..............................] - ETA: 1s - loss: 0.0136 - accuracy: 1.00 3/32 [=>............................] - ETA: 1s - loss: 0.0248 - accuracy: 0.96 5/32 [===>..........................] - ETA: 0s - loss: 0.0267 - accuracy: 0.98 7/32 [=====>........................] - ETA: 0s - loss: 0.0254 - accuracy: 0.98 9/32 [=======>......................] - ETA: 0s - loss: 0.0241 - accuracy: 0.9811/32 [=========>....................] - ETA: 0s - loss: 0.0253 - accuracy: 0.9813/32 [===========>..................] - ETA: 0s - loss: 0.0246 - accuracy: 0.9815/32 [=============>................] - ETA: 0s - loss: 0.0231 - accuracy: 0.9817/32 [==============>...............] - ETA: 0s - loss: 0.0231 - accuracy: 0.9819/32 [================>.............] - ETA: 0s - loss: 0.0231 - accuracy: 0.9821/32 [==================>...........] - ETA: 0s - loss: 0.0236 - accuracy: 0.9823/32 [====================>.........] - ETA: 0s - loss: 0.0238 - accuracy: 0.9825/32 [======================>.......] - ETA: 0s - loss: 0.0239 - accuracy: 0.9827/32 [========================>.....] - ETA: 0s - loss: 0.0243 - accuracy: 0.9729/32 [==========================>...] - ETA: 0s - loss: 0.0246 - accuracy: 0.9731/32 [============================>.] - ETA: 0s - loss: 0.0256 - accuracy: 0.9732/32 [==============================] - 1s 35ms/step - loss: 0.0256 - accuracy: 0.9760
Epoch 8/10
 1/32 [..............................] - ETA: 1s - loss: 0.0199 - accuracy: 0.96 3/32 [=>............................] - ETA: 1s - loss: 0.0191 - accuracy: 0.98 5/32 [===>..........................] - ETA: 1s - loss: 0.0166 - accuracy: 0.99 7/32 [=====>........................] - ETA: 0s - loss: 0.0179 - accuracy: 0.99 9/32 [=======>......................] - ETA: 0s - loss: 0.0181 - accuracy: 0.9911/32 [=========>....................] - ETA: 0s - loss: 0.0180 - accuracy: 0.9913/32 [===========>..................] - ETA: 0s - loss: 0.0182 - accuracy: 0.9915/32 [=============>................] - ETA: 0s - loss: 0.0186 - accuracy: 0.9917/32 [==============>...............] - ETA: 0s - loss: 0.0191 - accuracy: 0.9919/32 [================>.............] - ETA: 0s - loss: 0.0184 - accuracy: 0.9921/32 [==================>...........] - ETA: 0s - loss: 0.0190 - accuracy: 0.9923/32 [====================>.........] - ETA: 0s - loss: 0.0188 - accuracy: 0.9925/32 [======================>.......] - ETA: 0s - loss: 0.0186 - accuracy: 0.9927/32 [========================>.....] - ETA: 0s - loss: 0.0183 - accuracy: 0.9929/32 [==========================>...] - ETA: 0s - loss: 0.0181 - accuracy: 0.9931/32 [============================>.] - ETA: 0s - loss: 0.0180 - accuracy: 0.9932/32 [==============================] - 1s 35ms/step - loss: 0.0180 - accuracy: 0.9940
Epoch 9/10
 1/32 [..............................] - ETA: 1s - loss: 0.0098 - accuracy: 1.00 3/32 [=>............................] - ETA: 1s - loss: 0.0124 - accuracy: 1.00 5/32 [===>..........................] - ETA: 0s - loss: 0.0132 - accuracy: 0.99 7/32 [=====>........................] - ETA: 0s - loss: 0.0135 - accuracy: 0.98 9/32 [=======>......................] - ETA: 0s - loss: 0.0140 - accuracy: 0.9811/32 [=========>....................] - ETA: 0s - loss: 0.0134 - accuracy: 0.9913/32 [===========>..................] - ETA: 0s - loss: 0.0143 - accuracy: 0.9815/32 [=============>................] - ETA: 0s - loss: 0.0143 - accuracy: 0.9817/32 [==============>...............] - ETA: 0s - loss: 0.0145 - accuracy: 0.9819/32 [================>.............] - ETA: 0s - loss: 0.0137 - accuracy: 0.9921/32 [==================>...........] - ETA: 0s - loss: 0.0136 - accuracy: 0.9923/32 [====================>.........] - ETA: 0s - loss: 0.0140 - accuracy: 0.9925/32 [======================>.......] - ETA: 0s - loss: 0.0138 - accuracy: 0.9927/32 [========================>.....] - ETA: 0s - loss: 0.0135 - accuracy: 0.9929/32 [==========================>...] - ETA: 0s - loss: 0.0134 - accuracy: 0.9931/32 [============================>.] - ETA: 0s - loss: 0.0140 - accuracy: 0.9832/32 [==============================] - 1s 36ms/step - loss: 0.0139 - accuracy: 0.9900
Epoch 10/10
 1/32 [..............................] - ETA: 1s - loss: 0.0125 - accuracy: 1.00 3/32 [=>............................] - ETA: 1s - loss: 0.0104 - accuracy: 1.00 5/32 [===>..........................] - ETA: 1s - loss: 0.0084 - accuracy: 1.00 7/32 [=====>........................] - ETA: 0s - loss: 0.0098 - accuracy: 1.00 9/32 [=======>......................] - ETA: 0s - loss: 0.0101 - accuracy: 1.0011/32 [=========>....................] - ETA: 0s - loss: 0.0109 - accuracy: 0.9913/32 [===========>..................] - ETA: 0s - loss: 0.0106 - accuracy: 0.9915/32 [=============>................] - ETA: 0s - loss: 0.0102 - accuracy: 0.9917/32 [==============>...............] - ETA: 0s - loss: 0.0104 - accuracy: 0.9919/32 [================>.............] - ETA: 0s - loss: 0.0110 - accuracy: 0.9921/32 [==================>...........] - ETA: 0s - loss: 0.0106 - accuracy: 0.9923/32 [====================>.........] - ETA: 0s - loss: 0.0110 - accuracy: 0.9925/32 [======================>.......] - ETA: 0s - loss: 0.0107 - accuracy: 0.9927/32 [========================>.....] - ETA: 0s - loss: 0.0106 - accuracy: 0.9929/32 [==========================>...] - ETA: 0s - loss: 0.0103 - accuracy: 0.9931/32 [============================>.] - ETA: 0s - loss: 0.0104 - accuracy: 0.9932/32 [==============================] - 1s 36ms/step - loss: 0.0104 - accuracy: 0.9990
  1/313 [..............................] - ETA: 43s - loss: 0.0422 - accuracy: 0  7/313 [..............................] - ETA: 2s - loss: 0.0441 - accuracy: 0. 15/313 [>.............................] - ETA: 2s - loss: 0.0598 - accuracy: 0. 22/313 [=>............................] - ETA: 2s - loss: 0.0662 - accuracy: 0. 30/313 [=>............................] - ETA: 2s - loss: 0.0671 - accuracy: 0. 38/313 [==>...........................] - ETA: 1s - loss: 0.0685 - accuracy: 0. 46/313 [===>..........................] - ETA: 1s - loss: 0.0730 - accuracy: 0. 54/313 [====>.........................] - ETA: 1s - loss: 0.0746 - accuracy: 0. 61/313 [====>.........................] - ETA: 1s - loss: 0.0751 - accuracy: 0. 67/313 [=====>........................] - ETA: 1s - loss: 0.0762 - accuracy: 0. 74/313 [======>.......................] - ETA: 1s - loss: 0.0754 - accuracy: 0. 82/313 [======>.......................] - ETA: 1s - loss: 0.0751 - accuracy: 0. 89/313 [=======>......................] - ETA: 1s - loss: 0.0742 - accuracy: 0. 97/313 [========>.....................] - ETA: 1s - loss: 0.0737 - accuracy: 0.104/313 [========>.....................] - ETA: 1s - loss: 0.0738 - accuracy: 0.112/313 [=========>....................] - ETA: 1s - loss: 0.0737 - accuracy: 0.120/313 [==========>...................] - ETA: 1s - loss: 0.0750 - accuracy: 0.128/313 [===========>..................] - ETA: 1s - loss: 0.0752 - accuracy: 0.135/313 [===========>..................] - ETA: 1s - loss: 0.0760 - accuracy: 0.143/313 [============>.................] - ETA: 1s - loss: 0.0758 - accuracy: 0.150/313 [=============>................] - ETA: 1s - loss: 0.0758 - accuracy: 0.158/313 [==============>...............] - ETA: 1s - loss: 0.0756 - accuracy: 0.166/313 [==============>...............] - ETA: 1s - loss: 0.0743 - accuracy: 0.175/313 [===============>..............] - ETA: 0s - loss: 0.0722 - accuracy: 0.183/313 [================>.............] - ETA: 0s - loss: 0.0712 - accuracy: 0.191/313 [=================>............] - ETA: 0s - loss: 0.0714 - accuracy: 0.198/313 [=================>............] - ETA: 0s - loss: 0.0699 - accuracy: 0.207/313 [==================>...........] - ETA: 0s - loss: 0.0691 - accuracy: 0.215/313 [===================>..........] - ETA: 0s - loss: 0.0685 - accuracy: 0.223/313 [====================>.........] - ETA: 0s - loss: 0.0673 - accuracy: 0.231/313 [=====================>........] - ETA: 0s - loss: 0.0662 - accuracy: 0.239/313 [=====================>........] - ETA: 0s - loss: 0.0651 - accuracy: 0.247/313 [======================>.......] - ETA: 0s - loss: 0.0643 - accuracy: 0.255/313 [=======================>......] - ETA: 0s - loss: 0.0637 - accuracy: 0.263/313 [========================>.....] - ETA: 0s - loss: 0.0635 - accuracy: 0.271/313 [========================>.....] - ETA: 0s - loss: 0.0627 - accuracy: 0.278/313 [=========================>....] - ETA: 0s - loss: 0.0614 - accuracy: 0.286/313 [==========================>...] - ETA: 0s - loss: 0.0609 - accuracy: 0.294/313 [===========================>..] - ETA: 0s - loss: 0.0602 - accuracy: 0.301/313 [===========================>..] - ETA: 0s - loss: 0.0597 - accuracy: 0.309/313 [============================>.] - ETA: 0s - loss: 0.0602 - accuracy: 0.313/313 [==============================] - 2s 7ms/step - loss: 0.0602 - accuracy: 0.9154

***************** Summary *****************
Trained float model accuracy:  0.9154000282287598
Trained float model is saved in  ./my_model.h5


my_model.h5 が生成された。
Custom_OP_Workflow_8_221202.png
  1. 2022年12月02日 04:49 |
  2. Vitis-AI
  3. | トラックバック:0
  4. | コメント:0

Vitis HLS 2022.2 の新機能を確かめる5(hls::print 関数)

Vitis HLS 2022.2 の新機能を確かめる4(performance プラグマ4)”の続き。

前回は、ソフトウエアとして書いた AXI4 Master アクセスベースの sobel_fil_axim.cpp で performance プラグマなしとありの状態で、C コードの合成を行って比較した。今回は、hls::print 関数について調べてみよう。

hls::print 関数を使用するには、

#include "hls_print.h"

を書いて、

hls::print ("loop %d\n", i);

という様に書けば良いようだ。

早速、sobel_axis_RGB24.cpp に hls::print 関数を加えてみた。
インクルード文に

#include "hls_print.h"

を追加して、LOOP_Y の for ループの下に

hls::print("y = %d\n",y);

を追加した。
Vitis_HLS_2022_2_37_221130.png

C シミュレーションを行った。y の値が表示された。
Vitis_HLS_2022_2_31_221130.png
Vitis_HLS_2022_2_32_221130.png

C コードの合成を行った。結果を示す。
LOOP_Y の下にコードを書いたので、LOOP_Y と LOOP_X が独立したようだ。
Vitis_HLS_2022_2_33_221130.png

syn/verilog に sobel_axis_RGB24_printint.sv ファイルが生成されていた。
Vitis_HLS_2022_2_35_221130.png

sobel_axis_RGB24_printint.sv ファイルを示す。
Vitis_HLS_2022_2_36_221130.png

sobel_axis_RGB24_printint.sv ファイルが実行されるため、C/RTL 協調シミュレーションでも時刻と y の値が表示される。
Vitis_HLS_2022_2_34_221130.png

hls::print 関数使えそうだ。RTL シミュレーションでも値を表示してくれるのが良い。
  1. 2022年12月01日 04:00 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0