<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>파이쿵</title>
    <link>https://pythonkim.tistory.com/</link>
    <description>얼떨결에 붙인 이름 파이썬_킴</description>
    <language>ko</language>
    <pubDate>Wed, 22 Jul 2026 01:23:30 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>사과쿵</managingEditor>
    <image>
      <title>파이쿵</title>
      <url>https://t1.daumcdn.net/cfile/tistory/211AB7495706515D20</url>
      <link>https://pythonkim.tistory.com</link>
    </image>
    <item>
      <title>CNN 시각화 : 피처맵 (3)</title>
      <link>https://pythonkim.tistory.com/165</link>
      <description>&lt;p&gt;다 만들어진 예제를 정리해서 올리는 데만 3~4시간이 걸린다.&lt;br /&gt;올리려다 보면&lt;br /&gt;수업 시간에 말로 하던 부분을 다른 방식으로 표현하게 되고&lt;br /&gt;그러면서 내용이 추가된다.&lt;/p&gt;
&lt;p&gt;전체 코드를 사용하려면&lt;br /&gt;이전 글의 코드와 현재 글의 코드를 순서대로 나열해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;predict_and_get_outputs&lt;/span&gt;(model&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;img_path):&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# (conv, pool) 레이어만 출력. flatten 레이어 이전까지.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;layer_outputs = [layer.output &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;layer &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;model.layers[:&lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;]]&lt;br /&gt;    layer_names = [layer.name &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;layer &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;model.layers[:&lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;]]&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;([&lt;span style=&quot;color:#8888c6;&quot;&gt;str&lt;/span&gt;(output.shape) &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;output &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;layer_outputs])&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# ['(?, 148, 148, 32)', '(?, 74, 74, 32)', '(?, 72, 72, 64)', '(?, 36, 36, 64)',&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    #  '(?, 34, 34, 128)', '(?, 17, 17, 128)', '(?, 15, 15, 128)', '(?, 7, 7, 128)']&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 마지막 레이어에 해당하는 7번째 레이어의 출력만 전달해도 될 것 같지만, 7번째 결과만 나옴.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # train 연산에 loss가 포함되어 있지만, loss를 명시하지 않으면 결과를 얻지 못하는 것과 같다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;activation_model = tf.keras.models.Model(&lt;span style=&quot;color:#aa4926;&quot;&gt;inputs&lt;/span&gt;=model.input&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;outputs&lt;/span&gt;=layer_outputs)&lt;br /&gt;&lt;br /&gt;    input_shape = (model.input.shape[&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;model.input.shape[&lt;span style=&quot;color:#6897bb;&quot;&gt;2&lt;/span&gt;])      &lt;span style=&quot;color:#808080;&quot;&gt;# (150, 150)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;img_tensor = load_image(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;target_size&lt;/span&gt;=input_shape)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;layer &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;layer_outputs:&lt;br /&gt;        &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(layer.shape)&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;'-' &lt;/span&gt;* &lt;span style=&quot;color:#6897bb;&quot;&gt;50&lt;/span&gt;)&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# (?, 148, 148, 32)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 74, 74, 32)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 72, 72, 64)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 36, 36, 64)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 34, 34, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 17, 17, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 15, 15, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (?, 7, 7, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 앞에 나온 layer_outputs 변수를 덮어썼다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 하는 역할이 같고 미세한 부분이 다르지만 내용도 같기 때문에 다른 이름으로 만들 필요가 없다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;layer_outputs = activation_model.predict(img_tensor)&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;layer &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;layer_outputs:&lt;br /&gt;        &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(layer.shape)&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# (1, 148, 148, 32)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 74, 74, 32)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 72, 72, 64)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 36, 36, 64)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 34, 34, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 17, 17, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 15, 15, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # (1, 7, 7, 128)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;layer_outputs&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;layer_names&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;layer_outputs&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;layer_names = predict_and_get_outputs(model&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cat_path)&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;모델과 사진&amp;nbsp;경로를 전달하면 해당 레이어의 출력 결과를 알려주는 함수를 구현했다.&lt;br /&gt;이 코드에서 중요한 것은&lt;br /&gt;원하는 출력 결과가 레이어 8개의 결과이기 때문에&lt;br /&gt;8개의 연산이 들어있는 layer_outputs를 Model 객체를 생성할 때 전달하는 코드다.&lt;br /&gt;연산을 구동하면 출력이 나오고&lt;br /&gt;컨볼루션의 출력 결과를 피처맵이라고 부른다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;show_activation_maps&lt;/span&gt;(layer&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;title&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;layer_index&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;n_cols=&lt;span style=&quot;color:#6897bb;&quot;&gt;16&lt;/span&gt;):&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# size는 높이와 너비, 모두를 가리킨다. 가로/세로 크기가 같다. (150, 150)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;size&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;n_features = layer.shape[&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;layer.shape[-&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;assert &lt;/span&gt;n_features % n_cols == &lt;span style=&quot;color:#6897bb;&quot;&gt;0     &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# 반드시 나누어 떨어져야 한다&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;n_rows = n_features // n_cols&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 각각의 이미지를 따로 출력하지 않고, 큰 이미지에 모아서 한번에 출력하기 위한 변수&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;big_image = np.zeros((n_rows*size&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;n_cols*size)&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;dtype&lt;/span&gt;=np.float32)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 행과 열의 정해진 위치에 출력하기 위한 2차원 반복문&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;row &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;range&lt;/span&gt;(n_rows):&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;col &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;range&lt;/span&gt;(n_cols):&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;# 특정 부분에 값들이 편중되어 있는 상태&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            # 피처에 대해 반복하기 때문에 channel 변수는 피처맵 1개를 가리킨다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;channel = layer[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;:&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;:&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;row * n_cols + col]      &lt;span style=&quot;color:#808080;&quot;&gt;# shape : (size, size)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            # 특성이 잘 보이도록 0~255 사이로 재구성. 범위를 벗어나는 일부 값들은 클리핑.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            # 대략적으로 정규 분포에 따르면 95% 정도의 데이터 포함&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;channel -= channel.mean()&lt;br /&gt;            channel /= channel.std()&lt;br /&gt;            channel *= &lt;span style=&quot;color:#6897bb;&quot;&gt;64&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;            &lt;/span&gt;channel += &lt;span style=&quot;color:#6897bb;&quot;&gt;128&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;            &lt;/span&gt;channel = np.clip(channel&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;).astype(&lt;span style=&quot;color:#6a8759;&quot;&gt;'uint8'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;            &lt;span style=&quot;color:#808080;&quot;&gt;# 큰 이미지에서 자신의 영역을 찾아 복사&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;big_image[row*size:(row+&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;)*size&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;col*size:(col+&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;)*size] = channel&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 그래프에서는 행열(n_rows, n_cols) 순서가 xy로 바뀐다. n_cols가 앞에 와야 한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;plt.figure(&lt;span style=&quot;color:#aa4926;&quot;&gt;figsize&lt;/span&gt;=(n_cols&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;n_rows))&lt;br /&gt;&lt;br /&gt;    plt.xticks(np.arange(n_cols) * size)&lt;br /&gt;    plt.yticks(np.arange(n_rows) * size)&lt;br /&gt;    plt.title(&lt;span style=&quot;color:#6a8759;&quot;&gt;'layer {} : {}'&lt;/span&gt;.format(layer_index&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;title))&lt;br /&gt;    plt.tight_layout()&lt;br /&gt;    plt.imshow(big_image)           &lt;span style=&quot;color:#808080;&quot;&gt;# cmap='gray'&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;한 줄에 16개의 피처를 출력한다.&lt;br /&gt;모든 레이어의 필터 개수를 16의 배수로 설정했기 때문에&lt;br /&gt;한 줄에 16개씩 출력하는 코드는 현재 모델에 대해서는 동작하지만&lt;br /&gt;다른 모델에 대해서는 동작하지 않을 수 있다.&lt;/p&gt;
&lt;p&gt;이 함수는 피처맵에 포함된 전체 피처를 모두 출력한다.&lt;br /&gt;32개, 64개, 128개로 피처맵의 개수가 많아지는 것을 아래에서 볼 수 있다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;i&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;(layer&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;name) &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;enumerate&lt;/span&gt;(&lt;span style=&quot;color:#8888c6;&quot;&gt;zip&lt;/span&gt;(layer_outputs&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;layer_names)):&lt;br /&gt;    show_activation_maps(layer&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;name&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;i)&lt;br /&gt;&lt;br /&gt;plt.show()&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과를 보면&lt;br /&gt;레이어를 거쳐 갈수록, 정확하게는 풀링 레이어를 거칠 때마다&lt;br /&gt;피처맵의 크기가 절반으로 줄어드는 것을 확인할 수 있다.&lt;br /&gt;크기를 확인하기 위해 이번에는 일부러 눈금을 지우지 않고 두었다.&lt;/p&gt;
&lt;p&gt;또한 이전 예제에서는 gray 컬러맵을 사용했는데&lt;br /&gt;이번에는 viridis 기본 컬러맵을 사용했다.&lt;br /&gt;흑백이 좋을 때도 있고 제한된 색상으로 표시하는 것이 좋을 때도 있다.&lt;/p&gt;
&lt;p&gt;출력 결과에서 공백으로 표시되는 것은&lt;br /&gt;해당 필터가 현재 이미지에 반응하지 않았다는 것을 의미한다.&lt;br /&gt;결과물이 많아 고양이 사진만 사용했는데&lt;br /&gt;개 사진을 사용하면 공백이었던 필터에 결과가 나타날 수도 있다.&lt;br /&gt;또한 공백으로 가기 직전의 거의 공백처럼 보이는 피처맵도 있다.&lt;br /&gt;뜬금없이 공백이 표시되는 것은 아니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/999082495D2C09D92F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F999082495D2C09D92F&quot; width=&quot;900&quot; height=&quot;161&quot; filename=&quot;Figure_1.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/990486495D2C09DA33&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F990486495D2C09DA33&quot; width=&quot;900&quot; height=&quot;161&quot; filename=&quot;Figure_2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F7DC4E5D2C092B33&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F7DC4E5D2C092B33&quot; width=&quot;900&quot; height=&quot;250&quot; filename=&quot;Figure_3.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/999B9E4E5D2C092C24&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F999B9E4E5D2C092C24&quot; width=&quot;900&quot; height=&quot;250&quot; filename=&quot;Figure_4.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F29B4E5D2C092E33&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F29B4E5D2C092E33&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;Figure_5.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99248A4E5D2C092F31&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99248A4E5D2C092F31&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;Figure_6.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99DD9E4E5D2C09312B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99DD9E4E5D2C09312B&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;Figure_7.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F2CA435D2C093226&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F2CA435D2C093226&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;Figure_8.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>케라스</category>
      <category>CNN</category>
      <category>시각화</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/165</guid>
      <comments>https://pythonkim.tistory.com/165#entry165comment</comments>
      <pubDate>Mon, 15 Jul 2019 14:12:44 +0900</pubDate>
    </item>
    <item>
      <title>CNN 시각화 : 피처맵 (2)</title>
      <link>https://pythonkim.tistory.com/164</link>
      <description>&lt;p&gt;이전 글에서 얘기했던 것처럼&lt;br /&gt;지금부터 설명하는 코드는 &quot;케라스 창시자&quot;를 토대로 했고&lt;br /&gt;수업에 사용하기 위해서 필요하기는 하지만&lt;br /&gt;정해진 수업 시간을 넘어가는 부분에 대해서는 과감하게 정리를 했다.&lt;br /&gt;또한 나만의 스타일이 있어서&lt;br /&gt;내식대로 변수 이름부터 상당한 부분을 수정했음을 밝힌다.&lt;br /&gt;설명이 부족한 부분에 대해서는 &quot;케라스 창시자&quot;에 나오는 원본 코드를 참조하기 바란다.&lt;/p&gt;
&lt;p&gt;이번 코드를 구동하기 위해서는&lt;br /&gt;모델 파일과 시각화를 적용할 사진이 필요하다.&lt;br /&gt;모델 파일은 &quot;케라스 창시자&quot;에 나오는 두 번째 모델을 학습한 파일이고&lt;br /&gt;사진 파일은 도서에 첨부된 개와 고양이 파일 중에서 하나씩을 골랐다.&lt;br /&gt;다운로드 받은 파일은 cats_and_dogs 폴더를 만들고 그 안에 복사하도록 한다.&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://drive.google.com/open?id=1x4bgVQGhIfGvj9pz0j3bCelz7kQDui6h&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;개와 고양이 모델 파일 다운로드&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/open?id=1JIca4R555qgZVTqE-jHk4bw6vEHcCiVR&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;개 사진 다운로드&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/open?id=18OlodklWIeEOnNQY_7ruwuMLy--au-e2&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;고양이 사진 다운로드&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그러면 순서대로 전체 코드를 살펴보도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;tensorflow &lt;span style=&quot;color:#cc7832;&quot;&gt;as &lt;/span&gt;tf&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;numpy &lt;span style=&quot;color:#cc7832;&quot;&gt;as &lt;/span&gt;np&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;matplotlib.pyplot &lt;span style=&quot;color:#cc7832;&quot;&gt;as &lt;/span&gt;plt&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;show_image&lt;/span&gt;(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;target_size):&lt;br /&gt;    img = tf.keras.preprocessing.image.load_img(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;target_size&lt;/span&gt;=target_size)&lt;br /&gt;    img_tensor = tf.keras.preprocessing.image.img_to_array(img)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# print(img_tensor[0, 0])                         # [31.  2.  6.]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # print(np.min(img_tensor), np.max(img_tensor))   # 0.0 255.0&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # print(img_tensor.dtype, img_tensor.shape)       # float32 (150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 스케일링하지 않으면 이미지 출력 안됨&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;img_tensor /= &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;    &lt;/span&gt;plt.imshow(img_tensor)&lt;br /&gt;    plt.show()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;cat_path = &lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/cat.1574.jpg'&lt;br /&gt;&lt;/span&gt;dog_path = &lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/dog.1525.jpg'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;show_image(cat_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;target_size&lt;/span&gt;=(&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;))&lt;br /&gt;show_image(dog_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;target_size&lt;/span&gt;=(&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;))&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;특정 이미지를 화면에 표시하기 위해 만들었고&lt;br /&gt;실제로 사용하지는 않는다.&lt;br /&gt;전달한 이미지가 어떤 건지 확인하는 용도로 구현했다.&lt;br /&gt;가장 중요한 부분은 스케일링.&lt;br /&gt;딥러닝은 작은 숫자에 강하다고 해야 할까?&lt;br /&gt;숫자가 클 경우 수렴하는데 오래 걸리기 때문에 스케일링이 필요하다.&lt;br /&gt;원본은 0~255 사이의 RGB 정수 값을 갖기 때문에&lt;br /&gt;이를 0~1 사이의 실수로 변환하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;table cellspacing=&quot;5&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; align=&quot;center&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 450px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B9AB3F5D2BE1D12D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B9AB3F5D2BE1D12D&quot; width=&quot;450&quot; height=&quot;434&quot; filename=&quot;cat_1574.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 450px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992B413F5D2BE1D220&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992B413F5D2BE1D220&quot; width=&quot;450&quot; height=&quot;434&quot; filename=&quot;dog_1525.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;나름 귀여운 사진을 골랐다.&lt;br /&gt;피처맵을 출력할 때는 x축과 y축에 들어가는 눈금은 표시하지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# 4개의 예제 중에서 두 번째 예제 사용&lt;br /&gt;&lt;/span&gt;model_path = &lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs_2/cats_and_dogs_2.h5'&lt;br /&gt;&lt;/span&gt;model = tf.keras.models.load_model(model_path)&lt;br /&gt;model.summary()&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;먼저 모델을 로드해서 네트웍 구조를 보자.&lt;br /&gt;여러 개의 모델 중에서 굳이 성능이 좋지 않은 두 번째 모델을 사용한 이유가 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;_________________________________________________________________&lt;br /&gt;Layer (&lt;span style=&quot;color:#8888c6;&quot;&gt;type&lt;/span&gt;)                 Output Shape              Param &lt;span style=&quot;color:#808080;&quot;&gt;#   &lt;br /&gt;&lt;/span&gt;=================================================================&lt;br /&gt;conv2d_68 (Conv2D)           (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;148&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;148&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;32&lt;/span&gt;)      &lt;span style=&quot;color:#6897bb;&quot;&gt;896       &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;max_pooling2d_68 (MaxPooling (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;74&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;74&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;32&lt;/span&gt;)        &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;conv2d_69 (Conv2D)           (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;72&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;72&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;64&lt;/span&gt;)        &lt;span style=&quot;color:#6897bb;&quot;&gt;18496     &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;max_pooling2d_69 (MaxPooling (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;64&lt;/span&gt;)        &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;conv2d_70 (Conv2D)           (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;34&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;34&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;128&lt;/span&gt;)       &lt;span style=&quot;color:#6897bb;&quot;&gt;73856     &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;max_pooling2d_70 (MaxPooling (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;17&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;17&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;128&lt;/span&gt;)       &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;conv2d_71 (Conv2D)           (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;128&lt;/span&gt;)       &lt;span style=&quot;color:#6897bb;&quot;&gt;147584    &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;max_pooling2d_71 (MaxPooling (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;128&lt;/span&gt;)         &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;flatten_21 (Flatten)         (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;6272&lt;/span&gt;)              &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;dense_46 (Dense)             (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;512&lt;/span&gt;)               &lt;span style=&quot;color:#6897bb;&quot;&gt;3211776   &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;dropout_23 (Dropout)         (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;512&lt;/span&gt;)               &lt;span style=&quot;color:#6897bb;&quot;&gt;0         &lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;dense_47 (Dense)             (&lt;span style=&quot;color:#cc7832;&quot;&gt;None, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;)                 &lt;span style=&quot;color:#6897bb;&quot;&gt;513       &lt;br /&gt;&lt;/span&gt;=================================================================&lt;br /&gt;Total params: &lt;span style=&quot;color:#6897bb;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;453&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;121&lt;br /&gt;&lt;/span&gt;Trainable params: &lt;span style=&quot;color:#6897bb;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;453&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;121&lt;br /&gt;&lt;/span&gt;Non-trainable params: &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;br /&gt;&lt;/span&gt;_________________________________________________________________&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;뒤쪽 예제들은 VGG16 모델을 재사용하는 모델이라서&lt;br /&gt;레이어의 개수가 너무 많아서 보여줘야 하는 것들도 많기 때문에 적절하지 않다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;여기서 보려고 하는 것은&lt;br /&gt;필터 슬라이딩의 결과물인 피처맵이고&lt;br /&gt;풀링을 포함해도 8개밖에 없어서 비교가 쉽다.&lt;br /&gt;레이어 후반부에 해당하는 FC 레이어의 가중치는&lt;br /&gt;피처를 추출하는 것이 아니라 분류를 목적으로 하기 때문에 출력하지 않는다.&lt;/p&gt;
&lt;p&gt;궁금한 분들은 당연히 출력해서 결과를 확인하는 것도 좋을 것이다.&lt;br /&gt;그러나 문제가 있다.&lt;br /&gt;컨볼루션과 풀링에서는 정확하게 이미지 단위로 데이터가 존재하는 것에 반해&lt;br /&gt;FC(dense) 레이어에서는 1차원이고&lt;br /&gt;이걸 몇 개의 이미지로 분할할 것인지부터 크기를 어떻게 해야할지 막막하다.&lt;br /&gt;다시 말해 인접한 데이터를 이미지처럼 상하좌우로 붙여서 출력하기 어렵다.&lt;br /&gt;어떡해야 하는지는 나도 안해봐서 모른다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;어쨌거나 출력 결과에서 얘기하려고 하는 것은&lt;br /&gt;컨볼루션과 풀링에 해당하는 8개 레이어의 피처맵만 출력한다는 것.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;load_image&lt;/span&gt;(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;target_size):&lt;br /&gt;    img = tf.keras.preprocessing.image.load_img(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;target_size&lt;/span&gt;=target_size)&lt;br /&gt;    img_tensor = tf.keras.preprocessing.image.img_to_array(img)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 배치 사이즈 추가 + 스케일링 결과 반환&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;img_tensor[np.newaxis] / &lt;span style=&quot;color:#6897bb;&quot;&gt;255     &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# (1, 150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# 첫 번째 등장하는 컨볼루션 레이어의 모든 피처맵(32개) 출력&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;show_first_feature_map&lt;/span&gt;(loaded_model&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;img_path):&lt;br /&gt;    first_output = loaded_model.layers[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;].output&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(first_output.shape&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;first_output.dtype)   &lt;span style=&quot;color:#808080;&quot;&gt;# (?, 148, 148, 32) &amp;lt;dtype: 'float32'&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 1개의 출력을 갖는 새로운 모델 생성&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;model = tf.keras.models.Model(&lt;span style=&quot;color:#aa4926;&quot;&gt;inputs&lt;/span&gt;=loaded_model.input&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;outputs&lt;/span&gt;=first_output)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 입력으로부터 높이와 너비를 사용해서 target_size에 해당하는 튜플 생성&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;target_size = (loaded_model.input.shape[&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;loaded_model.input.shape[&lt;span style=&quot;color:#6897bb;&quot;&gt;2&lt;/span&gt;])&lt;br /&gt;    img_tensor = load_image(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;target_size)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(loaded_model.input.shape)     &lt;span style=&quot;color:#808080;&quot;&gt;# (?, 150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(img_tensor.shape)             &lt;span style=&quot;color:#808080;&quot;&gt;# (1, 150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;first_activation = model.predict(img_tensor)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 컨볼루션 레이어에서 필터 크기(3), 스트라이드(1), 패딩(valid)을 사용했기 때문에&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 150에서 148로 크기가 일부 줄었음을 알 수 있다. 필터 개수는 32.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(first_activation.shape)       &lt;span style=&quot;color:#808080;&quot;&gt;# (1, 148, 148, 32)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(first_activation[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;])    &lt;span style=&quot;color:#808080;&quot;&gt;# [0.00675746 0. 0.02397328 0.03818807 0. ...]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 19번째 활성 맵 출력. 기본 cmap은 viridis. gray는 흑백 컬러맵.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # [0, :, :, feature_index]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 0은 첫 번째 데이터(원본 이미지)의 피처맵을 가리킨다. 사진은 1장만 사용했기 때문에 0만 가능&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 가운데 콜론(:)은 높이와 너비를 가리키는 차원의 모든 데이터&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # feature_index는 보고 싶은 피처맵이 있는 채널을 가리킨다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 32개의 필터를 사용했다면 0부터 31까지의 피처맵이 존재한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;plt.figure(&lt;span style=&quot;color:#aa4926;&quot;&gt;figsize&lt;/span&gt;=(&lt;span style=&quot;color:#6897bb;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;))&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;i &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;range&lt;/span&gt;(first_activation.shape[-&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]):&lt;br /&gt;        plt.subplot(&lt;span style=&quot;color:#6897bb;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;i + &lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;# 눈금 제거. fignum은 같은 피켜에 연속 출력&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;plt.axis(&lt;span style=&quot;color:#6a8759;&quot;&gt;'off'&lt;/span&gt;)&lt;br /&gt;        plt.matshow(first_activation[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;:&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;:&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;i]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;cmap&lt;/span&gt;=&lt;span style=&quot;color:#6a8759;&quot;&gt;'gray'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;fignum&lt;/span&gt;=&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;)&lt;br /&gt;    plt.tight_layout()&lt;br /&gt;    plt.show()&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;개와 고양이 모델로부터 첫 번째 컨볼루션 레이어의 피처맵만 출력해 보자.&lt;br /&gt;이전 글에서처럼 전체 레이어를 비교하는 것도 중요하지만&lt;br /&gt;현재 피처에서 각각의 피처들이 어떤 역할을 했는지 비교하는 것도 중요하다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;아래의 한 줄짜리 코드를 통해 앞에서 정의한 함수가 어떻게 동작했는지 결과를 보도록 하자.&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;show_first_feature_map(model&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cat_path)&lt;br /&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9904E0495D2BFDC822&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9904E0495D2BFDC822&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;first_feature_maps_cat.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;show_first_feature_map(model&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;dog_path)&lt;br /&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9980F7505D2BFDEF22&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9980F7505D2BFDEF22&quot; width=&quot;900&quot; height=&quot;500&quot; filename=&quot;first_feature_maps_dog.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;첫 번째 레이어의 피처맵만 출력해도&lt;br /&gt;꽤 다양한 결과가 만들어졌다는 것을 알 수 있다.&lt;br /&gt;또한 지금은 비슷해 보여도&lt;br /&gt;두 번째 레이어로 넘어가면서 현저하게 달라지는 피처맵이 발생할 것이다.&lt;br /&gt;이렇게 여러 개의 컨볼루션을 수행하게 되면&lt;br /&gt;다양한 필터를 만나게 되고 결과적으로 하는 역할이 다른 피처맵이 만들어지게 된다.&lt;/p&gt;</description>
      <category>케라스</category>
      <category>CNN</category>
      <category>시각화</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/164</guid>
      <comments>https://pythonkim.tistory.com/164#entry164comment</comments>
      <pubDate>Mon, 15 Jul 2019 11:17:53 +0900</pubDate>
    </item>
    <item>
      <title>CNN 시각화 : 피처맵 (1)</title>
      <link>https://pythonkim.tistory.com/163</link>
      <description>&lt;p&gt;가끔 수업을 들으러 오는 수강생들로부터&lt;br /&gt;파이쿵 블로그에 대한 얘기를 듣는다.&lt;br /&gt;아직 내공이 깊지 않아&lt;br /&gt;기본적인 것들에 대해서만 게시하고 있을 뿐인데&lt;br /&gt;자주 방문했고 도움이 되었다고 한다.&lt;/p&gt;
&lt;p&gt;과거에 수업했던 자료들을 모두 올려놓긴 했지만&lt;br /&gt;최근 자료들은 괜히 부담스러워서 수업에서만 사용하고 있었는데&lt;br /&gt;수강생들의 얘기를 듣다 보니&lt;br /&gt;대단하지 않아도 많은 분들에게 보여드려야 하겠다는 압박을 은연 중에 받았다.&lt;/p&gt;
&lt;p&gt;&quot;케라스 창시자&quot;라는 도서에 딥러닝 관련 좋은 예제들이 많다.&lt;br /&gt;최근에 나온 책이라 모두 잘 동작하고&lt;br /&gt;박해선님께서 번역해서 번역도 깔끔하지만&lt;br /&gt;도서 하단의 역자 주가 아주 매력적인 책이다.&lt;br /&gt;최근의 수업에서는 이 책에 나오는 내용 일부를 수정해서 진행한다.&lt;br /&gt;수업을 진행하면서&lt;br /&gt;이 책에서 발췌했다고 하고&lt;br /&gt;괜히 무안해서 내 식대로 많이(?) 수정해서 사용한다고 얘기한다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://cs231n.github.io/convolutional-networks/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9918AF465D2BD0ED0D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9918AF465D2BD0ED0D&quot; width=&quot;900&quot; height=&quot;431&quot; filename=&quot;convnet.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;앞에 있는 사진이 딥러닝&amp;nbsp;기초를 수업할 때 가장 중요하게 생각하는 사진이다.&lt;br /&gt;이 사진 한 장이면 딥러닝이 무엇인지 알 수 있다고 수업을 한다.&lt;/p&gt;
&lt;p&gt;사진을 보면 레이어가 뒤쪽으로 넘어가면서&lt;br /&gt;모양이 선명하지 않고 뭉개지는 것을 볼 수 있다.&lt;br /&gt;이게 사람이 사물을 기억하는 방식이다.&lt;br /&gt;앞에서는 선명하게 기억하려고 노력하겠지만&lt;br /&gt;결국에는 사물에 대한 흐릿하게 기억할 수밖에 없다는 것을 보여준다.&lt;/p&gt;
&lt;p&gt;멀리서 엄마가 걸어오고 있다고 판단했지만&lt;br /&gt;가까이 와서 보니 엄마가 아니었다.&lt;br /&gt;이게 CNN이다.&lt;br /&gt;레이어 후반에 있는 흐릿한 이미지가 될 수 있는 사진은 매우 많다.&lt;br /&gt;선명한 사진을 압축하는 과정에서 동일한 이미지처럼 보여지는 것이다.&lt;/p&gt;
&lt;p&gt;CNN 아키텍처에서는 일반적으로 풀링(pooling)을 거치게 되면&lt;br /&gt;가로와 세로 크기가 절반으로 줄어든다.&lt;br /&gt;여기서 절반으로 줄어든다는 것은 필터 슬라이딩의 결과물인 피처 맵(feature map, activation map)이다.&lt;br /&gt;따라서 앞의 사진에서 주의해야 할 점은&amp;nbsp;&lt;br /&gt;레이어 뒤쪽으로 갈수록 크기가 줄어들고 있다는 점이다.&lt;br /&gt;다만 보기 좋게 출력하기 위해 모두 같은 크기로 했지만&lt;br /&gt;실제로는 풀링을 거칠수록 줄어들기 때문에 픽셀이 거칠게 표시되는 것이다.&lt;br /&gt;대신 채널(channel, 두께)의 깊이가 깊어진다.&lt;br /&gt;다만 이 사진에서는 특정 피처맵 하나만 출력해야 하기 때문에 채널을 표시할 수는 없다.&lt;/p&gt;
&lt;p&gt;참.. 앞의 사진이 피처맵을 보여준다는 것은 알고 있겠지?&lt;br /&gt;설마..&lt;/p&gt;
&lt;p&gt;CNN 아키텍처에서 이미지로 표현할 수 있는 데이터에 어떤 것이 있을까?&lt;br /&gt;가중치로 표현되는 필터와 필터의 결과물인 피처맵밖에 없다.&lt;br /&gt;피처맵은 컨볼루션과 풀링 레이어의 결과물이고&lt;br /&gt;첫 번째 입력인 원본 사진과 달리&lt;br /&gt;RGB 컴포넌트로 구성된 것이 아니라서 색상을 입힐 수가 없다.&lt;br /&gt;16개의 필터를 사용했다면 채널 16개인 피처맵이 만들어지고&lt;br /&gt;그중에서 1개의 피처맵만 표시하게 된다.&lt;/p&gt;
&lt;p&gt;사진 또는 이미지라고 불리는 것은&lt;br /&gt;픽셀이라는 형태로 표현되는 데이터이긴 하지만&lt;br /&gt;인접한 데이터(픽셀)는 연관성이 깊을 수밖에 없고&lt;br /&gt;이것을 상관관계가 강하다고 한다.&lt;br /&gt;내 친구가 검정이라면 나 또한 검정일 확률이 높다는 뜻이다.&lt;br /&gt;피처맵이 이미지는 아니지만&lt;br /&gt;이미지로 표시할 수 있는 데이터의 범위로 스케일링한다면&lt;br /&gt;각각의 픽셀(데이터)이 갖는 상관관계를 시각적으로 볼 수 있게 된다.&lt;/p&gt;
&lt;p&gt;실제로 표시를 해보면&lt;br /&gt;앞의 사진에서 보는 것처럼&lt;br /&gt;완전 엉뚱한 형태의 이미지가 나타나지 않는다는 것을 알 수 있다.&lt;br /&gt;원본 사진을 한 번 필터링했다고 해서&lt;br /&gt;자동차가 알 수 없는 무언가로 변하지는 않는다.&lt;/p&gt;
&lt;p&gt;간단하게 코드만 올리려고 했는데&lt;br /&gt;강사의 직업병으로 인해 설명이 길어졌다.&lt;br /&gt;코드는 다음 글에서 따로 게시한다.&lt;/p&gt;</description>
      <category>케라스</category>
      <category>CNN</category>
      <category>시각화</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/163</guid>
      <comments>https://pythonkim.tistory.com/163#entry163comment</comments>
      <pubDate>Mon, 15 Jul 2019 10:24:19 +0900</pubDate>
    </item>
    <item>
      <title>텐서플로 라이트 전체보기</title>
      <link>https://pythonkim.tistory.com/162</link>
      <description>&lt;p&gt;텐서플로 라이트는 여기까지.미안.&lt;br /&gt;
서버와 연동하는 모델과 연동하지 않고 독립적으로 동작하는 모델까지 모두 구현했으므로&lt;br /&gt;
내가 하려고 하는 정도로는 충분하다.&lt;br /&gt;
스마트폰과 연동하려고 한다면, 플러터와 함께 보는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul class=&quot;table_contents&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/132&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1. 텐서플로 라이트 : 안드로이드 기초(1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/133&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2. 텐서플로 라이트 : 안드로이드 기초(2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/134&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3. 텐서플로 라이트 : 안드로이드 기초(3)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/135&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;4. 텐서플로 라이트 : 안드로이드 + AND 모델(텐서플로) (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/136&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;5. 텐서플로 라이트 : 안드로이드 + AND 모델(텐서플로) (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/142&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;6. 텐서플로 라이트 : 안드로이드 + mnist 모델(케라스) (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/143&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;7. 텐서플로 라이트 : 안드로이드 + mnist 모델(케라스) (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/144&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;8. 플러터 : 플랫폼 채널 기본 (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/145&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;9. 플러터 : 플랫폼 채널 기본 (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/151&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;10. 플러터 : 개와 고양이 사진 분류 (케라스) (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/152&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;11. 플러터 : 개와 고양이 사진 분류 (케라스) (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/153&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;12. 플러터 : 개와 고양이 사진 분류 (케라스) (3)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/154&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;13. 플러터 : 개와 고양이 사진 분류 (케라스) (4)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/155&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;14. 플러터 : 개와 고양이 사진 분류 (케라스) (5)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>카테고리 전체보기</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/162</guid>
      <comments>https://pythonkim.tistory.com/162#entry162comment</comments>
      <pubDate>Fri, 7 Jun 2019 09:55:05 +0900</pubDate>
    </item>
    <item>
      <title>플러터 (스마트폰 앱) 전체보기</title>
      <link>https://pythonkim.tistory.com/161</link>
      <description>&lt;p&gt;미안.&lt;br /&gt;아빠가 목록을 빨리 만들어야 우재가 보기 편할텐데..&lt;br /&gt;많이 늦었네.&lt;br /&gt;티스토리는 한번에 다섯 개씩만 보여주게 되어 있어서 많이 불편해.&lt;br /&gt;지금 하고 있는 프로젝트.. 성공하길 바래!&lt;br /&gt;파이링~~&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul class=&quot;table_contents&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/100&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0. 플러터&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/101&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1. 플러터 : 텍스트&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/102&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2. 플러터 : 텍스트 스타일 (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/103&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3. 플러터 : 텍스트 스타일 (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/104&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;4. 플러터 : 텍스트 집합 (Stack)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/105&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;5. 플러터 : 텍스트 집합 (Row, Column)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/106&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;6. 플러터 : 텍스트 집합(Row + Column)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/107&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;7. 플러터 : 사진 (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/108&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;8. 플러터 : 사진 (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/109&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;9. 플러터 : 사진 배치&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/110&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;10. 플러터 : 사진 옵션(BoxFit)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/111&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;11. 플러터 : 버튼&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/112&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;12. 플러터 : 버튼 (Stateless vs. Stateful)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/113&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;13. 플러터 : 버튼 확장&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/114&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;14. 플러터 : 버튼 + 사진&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/115&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;15. 플러터 : 버튼 종류&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/116&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;16. 플러터 : 텍스트 입력&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/117&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;17. 플러터 : 로그인&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/118&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;18. 플러터 : 화면 이동(네비게이션)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/119&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;19. 플러터 : 탭바 기본&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/120&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;20. 플러터 : 탭바 기본 (아이콘 + 제목)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/121&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;21. 플러터 : 탭바&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/122&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;22. 플러터 : 목록 보기 (리스트뷰 기본)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/123&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;23. 플러터 : 목록 보기 (무제한)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/124&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;24. 플러터 : 목록 보기 (화면 전환)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/127&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;25. 플러터 : 텍스트 파일 읽기&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/128&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;26. 플러터 : 서버/클라이언트 연동 (1)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/129&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;27. 플러터 : 서버/클라이언트 연동 (2)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/130&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;28. 플러터 : 서버/클라이언트 연동 (3)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/146&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;29. 플러터 : 서버/클라이언트 연동 (4)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/147&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;30. 플러터 : 서버/클라이언트 연동 (5)&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;li&gt;&lt;a href=&quot;https://pythonkim.tistory.com/139&quot; target=&quot;_blank&quot; style=&quot;text-decoration:none&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;31. 플러터 : 앨범 + 카메라&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>카테고리 전체보기</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/161</guid>
      <comments>https://pythonkim.tistory.com/161#entry161comment</comments>
      <pubDate>Fri, 7 Jun 2019 09:54:26 +0900</pubDate>
    </item>
    <item>
      <title>서핑 트립 : 다대포 (2)</title>
      <link>https://pythonkim.tistory.com/157</link>
      <description>&lt;p&gt;대박의 꿈은 사라지고&lt;br /&gt;피로에 지친 육신만 남았다.&lt;br /&gt;다대포에 계속 있을 수는 없고 우리는 트립을 왔기 때문에&lt;br /&gt;송정으로 가기로 했다.&lt;br /&gt;배가 고팠는데, 얘기할 분위기가 아니었다.&lt;/p&gt;&lt;p&gt;송정에 도착하니 난리도 아니다.&lt;br /&gt;파도가 꽤 좋긴 했는데, 라인업에 사람들이 무지하게 늘어서 있었다.&lt;br /&gt;서프홀릭에서 보드를 빌린다.&lt;br /&gt;서프홀릭은 라인업까지는 다대포의 10분의 1도 안된다.&lt;br /&gt;차가 많이 다니지 않는 길 건너면 백사장, 그 앞에 바로 라인업.&lt;/p&gt;&lt;p&gt;로컬 서퍼분들과 재호 선생님이 흥분 했다.&lt;br /&gt;다대포를 만회해야한다는 생각이 너무 보였다.&lt;br /&gt;바다에서는 각자 인생을 가는 거다.&lt;br /&gt;입수. 열심히 즐겼다.&lt;/p&gt;&lt;p&gt;마침 파도가 내가 타기에 적당한 수준이었다.&lt;br /&gt;아침보다 줄었다고 하는데..&lt;br /&gt;사람도 처음보다 빠지고 해서 아주 좋았다.&lt;br /&gt;근데 너무 힘들었다.&lt;br /&gt;나는 한 시간쯤 타고 나왔고 나머지 분들은 조금 더 타고 나왔다.&lt;br /&gt;모두 엄청 상기된 상태였다.&lt;br /&gt;무지하게 많이 탔다고 열변을 토한다.&lt;/p&gt;&lt;p&gt;나는 정상적인 파도는 타지 못했다.&lt;br /&gt;라인업에서 파도가 부서지기 전에 탔어야 했는데&lt;br /&gt;피크가 깨지고 나서 거품이 되었을 때 두세&amp;nbsp;개 정도 탔다.&lt;br /&gt;피크에서 타는 것과는 천지차이.&lt;br /&gt;그래도 좋았다.&lt;/p&gt;&lt;p&gt;점심을 먹어야 하는데 분위기가 이상하다.&lt;br /&gt;다대포 파도가 살아났단다.&lt;br /&gt;다대포로 다시 갈 것이냐 송정에서 나머지 시간을 보낼 것이냐!&lt;br /&gt;부산의 양끝이라 1시간 걸린다.&lt;br /&gt;저녁에 죽도 갈 때도 그만큼 시간이 더 걸릴 것이다.&lt;br /&gt;유명한 개미집에 가서 얘기하기로 한다.&lt;br /&gt;사실 얘기할 필요도 없다.&lt;br /&gt;결정된 상태였지만 괜히 미안해서 결정을 연기한 것뿐이었다.&lt;/p&gt;&lt;p&gt;캠프생들이 신경 쓰였을 것이다.&lt;br /&gt;나는 전혀 상관없었고&lt;br /&gt;멘탈이 나갈 뻔 했던 그곳을 다시 방문하는 것도 멘탈에 좋을 것 같았다.&lt;br /&gt;여자 캠프생 둘도 좋다고 한다.&lt;br /&gt;그래서 물어봤다.&lt;br /&gt;보드 또 빌려야 하냐고. 우리는 오늘 두 번 빌렸다.&lt;br /&gt;다행스럽게 그냥 빌려주셨다.&lt;/p&gt;&lt;p&gt;다시 다대포.&lt;br /&gt;아까와는 다르게 바람 한점 없고 파도는 말랑말랑하다.&lt;br /&gt;좋은 파도라는 것을 설악과 죽도만 경험한 나도 알 정도였다.&lt;br /&gt;송정보다 훨씬 좋았다.&lt;br /&gt;일단 서퍼가 많이 없어서 라인업에서 겹치지 않고 앉을 수 있었다.&lt;/p&gt;&lt;p&gt;대박, 대박!&lt;br /&gt;라인업의 오른쪽 끝에 있었는데..&lt;br /&gt;파도가 오기 전에 일찌감치 패들링으로 보드를 움직이고&lt;br /&gt;가까이 왔을 때 폭풍 패들링을 해서 파도를 잡았다.&lt;br /&gt;다른 서퍼들이 하는 것처럼!&lt;br /&gt;상상할 수 없이 어설펐겠지만 서핑 인생 첫 번째 성공이었다.&lt;/p&gt;&lt;p&gt;그 후로 몇 개의 파도를 더 잡을 수 있었고&lt;br /&gt;파도 위에 있을 때의 기분도 충분히 느낄 수 있었다.&lt;br /&gt;살이 쪄서 파도가 날 무거워한다고 생각했었다.&lt;br /&gt;문제는 타이밍이었다.&lt;br /&gt;파도타기의 정석이랄까..&lt;br /&gt;지켜야 할 규칙이 있는데, 규칙을 전혀 지키지 않고 있었던 것이었다.&lt;br /&gt;지킨다고 생각한 건 나의 착각.&lt;/p&gt;&lt;p&gt;해피엔딩.&lt;br /&gt;다대포에서 최악의 서핑과 최선의 서핑을 모두 맛봤다.&lt;br /&gt;스스로 파도를 잡을 수 있음을 증명했다.&lt;br /&gt;등대까지의 패들링도 효과를 입증했고&lt;br /&gt;등대 앞에서의 보드 컨트롤,&lt;br /&gt;라인업 한쪽에서의 보드 컨트롤도 입증했다.&lt;br /&gt;보드 날려먹지 않고 비슷한 정도로 기다렸고 잡았다!&lt;/p&gt;&lt;p&gt;죽도에 도착하니 새벽 1시.&lt;br /&gt;차를 타고 오면서&lt;br /&gt;파도를 기다릴 때부터 테이크옵해서 일어날 때까지의 상황을 &lt;br /&gt;여러 번에 걸쳐 이미지 트레이닝했다.&lt;br /&gt;예전과는 다르게 테이크옵할 때의 중요한 점, 보드의 각도 등이 상상된다.&lt;/p&gt;&lt;p&gt;다음엔 만리포를 말씀하신다.&lt;br /&gt;월요일에 역대급 파도가 만리포에 들어와서 모두를 흥분시켰다.&lt;br /&gt;대한민국에서 볼 수 없는 수준의 파도였다.&lt;/p&gt;&lt;p&gt;난 아무 곳이나 오케이!&lt;br /&gt;재호 선생님이 아니어도 로컬 서퍼가 없어도&lt;br /&gt;서핑은 그냥 재밌다. 딴 동네 가서 하면 더 재밌다!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998BA7385CEE3F7A30&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F998BA7385CEE3F7A30&quot; width=&quot;900&quot; height=&quot;900&quot; filename=&quot;다대포_6.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9957BA385CEE3F7A01&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9957BA385CEE3F7A01&quot; width=&quot;900&quot; height=&quot;675&quot; filename=&quot;다대포_7.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>서핑일기</category>
      <category>다대포</category>
      <category>망고서프</category>
      <category>서핑</category>
      <category>양양 서핑</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/157</guid>
      <comments>https://pythonkim.tistory.com/157#entry157comment</comments>
      <pubDate>Wed, 29 May 2019 16:59:44 +0900</pubDate>
    </item>
    <item>
      <title>서핑 트립 : 다대포 (1)</title>
      <link>https://pythonkim.tistory.com/156</link>
      <description>&lt;p&gt;초밥을 벗어나기 전에&lt;br /&gt;서핑 중에 느꼈던 어려웠던 점을 정리하려고 했는데&lt;br /&gt;놀기도 해야 하고 공부도 해야 하고 돈도 벌어야 해서..&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;할 수 없다.&lt;br /&gt;머리에서 사라지기 전에 첫 번째 서핑 여행을 정리하는 것이 맞다.&lt;br /&gt;5월 마지막 주 월화수 3일의 시간이 생겼다.&lt;br /&gt;수요일은 어떻게 될지 몰랐지만&lt;br /&gt;월요일과 화요일 이틀은 망고서프에서 보내려고 했다.&lt;br /&gt;결국 수요일은 집에 왔고&lt;br /&gt;도서관에 나와 밀렸던 뒷정리 하고, 지금 이 글을 쓰고 있다.&lt;/p&gt;
&lt;p&gt;토요일인가 일요일인가..&lt;br /&gt;재호 선생님께서 트립 간다고 전화를 주셨다.&lt;br /&gt;망고서프는 월요일과 화요일 이틀 쉰다고.&lt;br /&gt;다대포 갈건데 같이 갈거냐고.&lt;/p&gt;
&lt;p&gt;월요일 오전에 도착해서 늘 하던대로 등대까지 패들링.&lt;br /&gt;(물론 나하고는 그다지 상관없을 수 있지만)&lt;br /&gt;저녁 전에는 파도가 꽤 좋아서&lt;br /&gt;보드 컨트롤과 실제 파도 잡는 연습을 했다.&lt;br /&gt;참.. 뭐라고 해야 할지..&lt;br /&gt;시도는 무지하게 했고 잡지는 못했고.&lt;br /&gt;그래도 잡은 것도 아니고&lt;br /&gt;잡지 못했다고 얘기하기는 싫은 상황이 몇 번은 있었다.&lt;br /&gt;중요한 점은 내가 라인업과 같은 라인에 있었다는 점이다.&lt;br /&gt;아직까지는 라인업에 있으면 주요 길목을 막아버리는 길막이다.&lt;/p&gt;
&lt;p&gt;참, 일요일 배드민턴 대회가 있어&lt;br /&gt;기분 좋게 승급을 하고 점심 먹고 나와서 발목을 접질렀다.&lt;br /&gt;다대포를 가야 하는데 구경만 해야 하는 상황.&lt;br /&gt;발목 나갈 각오를 하고 바다에 들어간 상황이었는데&lt;br /&gt;놀랍게도 바다에서 나오니 발목이 거의 아프지 않았다.&lt;br /&gt;발목을 쓸 일이 없어 시도하긴 했지만 놀라웠다.&lt;/p&gt;
&lt;p&gt;어찌 됐든&lt;br /&gt;저녁 7시. 다대포로 출발.&lt;br /&gt;서퍼라면 누구나 만나보고 교류하길 원하는&lt;br /&gt;죽도 로컬 서퍼 세 분과 함께 였다.&lt;br /&gt;여기에 재호 선생님, 나.&lt;br /&gt;같이 캠프에 참가했던 두 사람은 다대포에서 합류. 총 7명이었다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99C3ED495CEE3E523D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99C3ED495CEE3E523D&quot; width=&quot;900&quot; height=&quot;676&quot; filename=&quot;다대포_4.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;열심히 달려 자정이 되기 전에 도착해서&lt;br /&gt;늦은 저녁을 거하게 먹고&lt;br /&gt;모두가 하나 된다는 원모텔에 숙소를 잡았다.&lt;br /&gt;참고로 다대포나 송정은 접근성이 너무 좋아서 게스트하우스가 없다.&lt;br /&gt;원모델에서도 맥주 몇 캔을 마시고 나니 새벽 2시.&lt;br /&gt;재호 선생님과 남자 로컬 서퍼 두 분은 3시까지 담소.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;새벽 6시에 기상해서 힐링서프로 갔다.&lt;br /&gt;나를 포함한 캠프생들은 그 시간에 보드를 빌릴 수 있었다.&lt;br /&gt;차트가 잘 나온 날에는&lt;br /&gt;새벽부터 손님이 많다고 했다.&lt;br /&gt;굳이 죽도에서 다대포까지 왜 왔겠는가!&lt;br /&gt;그 놈의 차트가 대박 파도 터진다고 해서 온 것 아니겠는가!&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99071B495CEE3E5102&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99071B495CEE3E5102&quot; width=&quot;900&quot; height=&quot;675&quot; filename=&quot;다대포_1.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;7시가 조금 못 되어서 입수.&lt;br /&gt;하얀 거품이 엄청 길게 퍼지는 모습이 장관이었다.&lt;br /&gt;죽도와 달리 힐링서프에서 백사장까지&lt;br /&gt;4차선 도로를 건너고 공영 주차장을 지나&lt;br /&gt;시민들의 휴식처인 공원까지 지나고&lt;br /&gt;매우 넓은 백사장을 지나 그 만큼의 갯벌을 지나야&lt;br /&gt;라인업 초입에 도착할 수 있었다.&lt;br /&gt;간만의 차가 심한 곳이었다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992C28495CEE3E5218&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992C28495CEE3E5218&quot; width=&quot;900&quot; height=&quot;675&quot; filename=&quot;다대포_2.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;헐.. 바람이 불고 조류가 많이 셌다.&lt;br /&gt;그래도 깊지 않아 힘들지만 파도를 뚫고 라인업까지 갔다.&lt;br /&gt;등대까지 다녔던 패들링이 효과를 봤다.&lt;/p&gt;
&lt;p&gt;그런데 문제가 생겼다.&lt;br /&gt;임대한 스펀지 보드가 그동안 타던 것하고 너무 달라&lt;br /&gt;컨트롤을 전혀 할 수가 없었다.&lt;br /&gt;라인업까지 나갈 때도 좌우로 흔들리는 것은 기본이고&lt;br /&gt;패들링하다 미끄러지는 일까지 생겼다.&lt;br /&gt;라인업에서 보드에 앉아 파도를 기다려야 하는데&lt;br /&gt;앉아 있을 수가 없었다. 바람 때문에 보드 방향조차 돌릴 수가 없었다.&lt;/p&gt;
&lt;p&gt;보드에 앉았다 넘어졌다를 몇 번 반복하고 나니까&lt;br /&gt;백사장 왼쪽에 있는 산책로가 있는 갯바위에 가까이 가 있었다.&lt;br /&gt;서퍼 몇이 있기는 했지만&lt;br /&gt;선생님을 찾아 반대편으로 겁나게 패들링을 했다.&lt;br /&gt;15분쯤 하지 않았을까?&lt;br /&gt;느낌이 이상했다.&lt;br /&gt;좀 가깝게 간 것 같기는 한데&lt;br /&gt;가까워졌다고 얘기하기도 뭐한 거리만큼 이동했다.&lt;br /&gt;잠깐 쉬면 원래 자리로 돌아간다.&lt;br /&gt;헐.. 살짝 겁 났다.&lt;/p&gt;
&lt;p&gt;그만큼의 패들링을 다시 했고&lt;br /&gt;그제서야 선생님을 만날 수 있었다.&lt;br /&gt;너무 안심했지만&lt;br /&gt;실제로는 내가 선생님쪽으로 간게 아니고&lt;br /&gt;재호 선생님이 조류에 밀려 내쪽으로 온 것이었다.&lt;br /&gt;함께 처음 자리로 돌아가려고 했고&lt;br /&gt;선생님을 따라 갈 수 있으리라고 여겼지만&lt;br /&gt;선생님만 갔고 나는 남았다.&lt;/p&gt;
&lt;p&gt;그래도 처음 라인업이라고 생각했던 곳으로 계속 패들링.&lt;br /&gt;주변에 있던 서퍼들은 어느샌가 보이지 않는다.&lt;br /&gt;내가 갔는지 그들이 왔는지 모르는 상황, 캠프생 둘이 함께 있다.&lt;br /&gt;너무 반가워서 인사를 하고&amp;nbsp;&lt;br /&gt;이때까지도 나가야 한다는 생각을 못했다.&lt;br /&gt;캠프생들이 여기서 파도를 잡고 있었다,라고 생각을 했었다.&lt;br /&gt;두 사람이 바닷가쪽으로 이동하기에&lt;br /&gt;파도라서 하나 잡아보려는 시도는 해봐야 할 것 같아서&lt;br /&gt;몇 개 잡아보는 척 했고 다시 혼자가 됐다.&lt;/p&gt;
&lt;p&gt;나가기 위해 패들링을 했다.&lt;br /&gt;아까보다 현격하게 이동하는 거리가 짧아졌다.&lt;br /&gt;좀 전에는 짧기는 했지만 이동하는 느낌이 있었는데&lt;br /&gt;움직이긴 하는데.. 움직이는 것 같지 않은 느낌이랄까..&lt;/p&gt;
&lt;p&gt;패들링을 얼마나 했는지도 모르겠다.&lt;br /&gt;백사장으로 나가는 걸 포기하고&lt;br /&gt;숲이 있는 갯바위로 방향을 바꿨다.&lt;br /&gt;앞서 몇 명이 그쪽으로 나가는 것을 봤었고 바보 같다는 생각을 했었다.&lt;br /&gt;이런 조류와 바람이 산책로가 있는 곳으로 가지 않고&lt;br /&gt;바다쪽으로 나를 밀어붙였다.&lt;br /&gt;겁나게 패들링을 해도 갯바위하고 점점 멀어지는 느낌이다.&lt;br /&gt;패들링하는 오른쪽은 망망대핸데..&lt;/p&gt;
&lt;p&gt;삐뽀삐뽀.&lt;br /&gt;어디선가 사이렌 소리가 울린다.&lt;br /&gt;해양 경찰이 출동했다. 배가 두 대나 왔다.&lt;br /&gt;뭐라고 하는데.. 잘 안 들렸다.&lt;br /&gt;자존심이 남아서 그랬을까, 갯바위쪽으로 가는 중이라고 했다.&lt;br /&gt;가까이 오지 않은 상태에서 손짓으로 오라고 한다.&lt;br /&gt;마지 못해 갔다.&lt;br /&gt;조류와 바람을 등에 업으니까 꽤 먼 거리였는데 금방 도착했다.&lt;br /&gt;해양 경찰 한 분이 바다에 뛰어들어 쏘세지 하나를 건네주고 잡이라 한다.&lt;br /&gt;배까지의 거리는 얼마 안 되는데.. 잡았다.&lt;br /&gt;헤엄치면서 나를 끌어가려 하는데 앞으로 가질 않는다.&lt;br /&gt;내가 보드 위에서 물장구를 쳐서 도와드렸다.&lt;/p&gt;
&lt;p&gt;나는 첫 번째 구조자였다.&lt;br /&gt;가장 먼저, 가장 멀리 떠내려간 서퍼였던 것이다.&lt;br /&gt;총 9명이 구조되었고 8명은 두 번째 배로 구조되었다.&lt;br /&gt;그 중에는 로컬 서퍼도 한 분 계셨다.&lt;br /&gt;나하고 비슷하거나 더 있어 보이는 분이었는데&lt;br /&gt;다대포에서 활동하시는 로컬 서퍼로써 화가 많이 나보였다.&lt;/p&gt;
&lt;p&gt;해양 경찰이 모는 배로 먼 바다를 여행하니 좋았다.&lt;br /&gt;나 말고 모두 기분이 나빠 보였다.&lt;br /&gt;망고서프의 이름을 알리지 않기 위해 서울에서 왔다고 했다.&lt;br /&gt;배에 계신 분들이 친절하게 해주셨고&lt;br /&gt;왜 이 날씨에 바다에 나갔냐고 뭐라 하지 않았다.&lt;/p&gt;
&lt;p&gt;다대포항에 도착했는데 해수욕장까지는 직접 가라고 한다.&lt;br /&gt;헐.&lt;br /&gt;우리 모두는 슈트를 입었고 신발도 전화도 없다.&lt;br /&gt;있는 거라곤 거추장스러운 보드뿐!&lt;br /&gt;경찰이 힐링서프에 전화를 해줬고 선생님께서 오셨다.&lt;br /&gt;너무 놀래서 얼굴이 하애지셨다.&lt;br /&gt;회센터 아주머니와 대화 중이던 나는&lt;br /&gt;너무 즐겁게 웃고 하는 바람에 혼났다.&lt;br /&gt;캠프생하고 트립 왔는데.. 그 심정 오죽 했겠는가!&lt;/p&gt;
&lt;p&gt;로컬 서퍼분들도 그렇고 선생님도 그렇고&lt;br /&gt;간신히 빠져나왔다고 했다.&lt;br /&gt;평생 이런 조류와 바람은 처음이었다고.&lt;br /&gt;우리가 구조된 이후로 다대포는 임시 폐쇄되었다.&lt;/p&gt;
&lt;p&gt;여기서 놀라운 점 하나.&lt;br /&gt;두 시간을 패들링하고 조류와 바람에 시달렸음에도&lt;br /&gt;패들링할 수 있는 힘이 남아 있었다.&lt;br /&gt;패들링은 어꺠로 하는 게 아니라 등으로 하는 거다.&lt;/p&gt;</description>
      <category>서핑일기</category>
      <category>다대포</category>
      <category>망고서프</category>
      <category>서핑</category>
      <category>양양 서핑</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/156</guid>
      <comments>https://pythonkim.tistory.com/156#entry156comment</comments>
      <pubDate>Wed, 29 May 2019 16:36:32 +0900</pubDate>
    </item>
    <item>
      <title>14. 플러터 : 개와 고양이 사진 분류 (케라스) (5)</title>
      <link>https://pythonkim.tistory.com/155</link>
      <description>&lt;p&gt;이번 프로젝트는 너무 힘들었기에&lt;br /&gt;문제를 해결하는데 사용했던 몇 가지 함수를 정리한다.&lt;br /&gt;훨씬 더 많은 코드를 만들어서 검증했지만&lt;br /&gt;완성하고 나서 보니 대부분은 의미 없었던 함수였다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;첫 번째는 지정한 사진에 대해 정확도를 보여주는 코드다.&lt;br /&gt;에뮬레이터에서 시험해 보면&lt;br /&gt;결과가 너무 말도 안되게 나와서 어떤 문제인지 먼저 찾아야 했다.&lt;br /&gt;데스크탑에서도 똑같이 말도 안되게 나오는지 확인이 필요했다.&lt;/p&gt;
&lt;p&gt;나의 실수로 서로 다른 파일을 사용했던 관계로&lt;br /&gt;데스크탑에서는 결과가 너무 잘 나왔다.&lt;br /&gt;개와 고양이 모델 파일을 여러 개 만드는 과정에서 발생한&lt;br /&gt;말도 안되는 실수로 일 주일은 날려 먹었다.&lt;/p&gt;
&lt;p&gt;어쨌든 데스크탑과 스마트폰에서&lt;br /&gt;동일한 결과가 나온다는 것을 검증하는 것은 중요하다.&lt;br /&gt;물론 변환을 거쳤기 때문에 미세한 오차가 발생하는 것은 감안해야 한다.&lt;/p&gt;
&lt;p&gt;scaling 옵션에 따라 결과가 다르게 나오는 점도 확인해야 한다.&lt;br /&gt;True 옵션을 사용하는 것이 맞다.&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;tensorflow &lt;span style=&quot;color:#cc7832;&quot;&gt;as &lt;/span&gt;tf&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;from &lt;/span&gt;PIL &lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;Image&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;numpy &lt;span style=&quot;color:#cc7832;&quot;&gt;as &lt;/span&gt;np&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;load_image&lt;/span&gt;(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;scaling):&lt;br /&gt;    img = Image.open(img_path)&lt;br /&gt;    img = img.resize([&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;])&lt;br /&gt;    img.load()&lt;br /&gt;    data = np.float32(img)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 스케일링 유무에 따라 결과가 달라진다. 하는 것이 좋은 결과를 만든다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 학습할 때 스케일링을 적용했기 때문에 여기서도 적용하는 것이 맞다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;scaling:&lt;br /&gt;        data /= &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;data&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;predict_model&lt;/span&gt;(model_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;images&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;scaling):&lt;br /&gt;    model = tf.keras.models.load_model(model_path)&lt;br /&gt;&lt;br /&gt;    stack = []&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;img_path &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;images:&lt;br /&gt;        d = load_image(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;scaling&lt;/span&gt;=scaling)&lt;br /&gt;&lt;br /&gt;        d = d[np.newaxis]   &lt;span style=&quot;color:#808080;&quot;&gt;# (150, 150, 3) ==&amp;gt; (1, 150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;stack.append(d)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# (1, 150, 150, 3)으로 구성된 배열 결합 ==&amp;gt; (4, 150, 150, 3)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;data = np.concatenate(stack&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;axis&lt;/span&gt;=&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;    preds = model.predict(data)&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(preds.reshape(-&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;images = [&lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/small/test/cats/cat.1500.jpg'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/small/test/cats/cat.1501.jpg'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/small/test/dogs/dog.1500.jpg'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'cats_and_dogs/small/test/dogs/dog.1501.jpg'&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;predict_model(&lt;span style=&quot;color:#6a8759;&quot;&gt;'models/cats_and_dogs_small_4.h5'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;images&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;scaling&lt;/span&gt;=&lt;span style=&quot;color:#cc7832;&quot;&gt;False&lt;/span&gt;)&lt;br /&gt;predict_model(&lt;span style=&quot;color:#6a8759;&quot;&gt;'models/cats_and_dogs_small_4.h5'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;images&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;scaling&lt;/span&gt;=&lt;span style=&quot;color:#cc7832;&quot;&gt;True&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# False : [0. 0. 1. 1.]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# True  : [0.00184013 0.00273606 0.94292957 0.9738878 ]&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;앞의 코드보다 더 중요한 것이 있다.&lt;br /&gt;같은 모델이라도 변환을 거쳤기 때문에&lt;br /&gt;그 과정에서 원하지 않던 결과가 나올 수도 있다.&lt;/p&gt;
&lt;p&gt;스마트폰에 사용한 모델을 데스크탑에서 사용할 수 있으면 좋지 않을까?&lt;br /&gt;그래서 준비했다.&lt;br /&gt;텐서플로 라이트 모델을 데스크탑에서 사용하는 코드.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;test_tflite_model&lt;/span&gt;(tflite_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;images):&lt;br /&gt;    interpreter = tf.lite.Interpreter(&lt;span style=&quot;color:#aa4926;&quot;&gt;model_path&lt;/span&gt;=tflite_path)&lt;br /&gt;    interpreter.allocate_tensors()&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 입력 텐서 정보 : 인덱스를 알아야 데이터를 전달할 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;input_details = interpreter.get_input_details()&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# [{'name': 'conv2d_60_input', 'index': 3, 'shape': array([  1, 150, 150,   3], dtype=int32),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    #   'dtype': &amp;lt;class 'numpy.float32'&amp;gt;, 'quantization': (0.0, 0)}]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    # 출력 텐서 정보 : 인덱스를 알아야 결과를 받아올 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;output_details = interpreter.get_output_details()&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# [{'name': 'dense_41/Sigmoid', 'index': 18, 'shape': array([1, 1], dtype=int32),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    #   'dtype': &amp;lt;class 'numpy.float32'&amp;gt;, 'quantization': (0.0, 0)}]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;result = []&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;img_path &lt;span style=&quot;color:#cc7832;&quot;&gt;in &lt;/span&gt;images:&lt;br /&gt;        input_data = load_image(img_path&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;scaling&lt;/span&gt;=&lt;span style=&quot;color:#cc7832;&quot;&gt;True&lt;/span&gt;)&lt;br /&gt;        input_data = input_data[np.newaxis]&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;# 입력 데이터 전달&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;interpreter.set_tensor(input_details[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6a8759;&quot;&gt;'index'&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;input_data)&lt;br /&gt;        interpreter.invoke()&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;# 출력 데이터 읽기&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;output_data = interpreter.get_tensor(output_details[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6a8759;&quot;&gt;'index'&lt;/span&gt;])&lt;br /&gt;        result.append(output_data)&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 1차원 변환 출력&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(np.reshape(result&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;-&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#808080;&quot;&gt;# 텐서플로 라이트 모델 경로와 시험할 사진 경로 전달&lt;br /&gt;&lt;/span&gt;test_tflite_model(&lt;span style=&quot;color:#6a8759;&quot;&gt;'models/cats_and_dogs.tflite'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;images)&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;위의 코드는 내가 만든 코드는 아니고 스택 오버플로우를 참고했다.&lt;br /&gt;여기서는 난수를 사용해서 어떤 데이터에 대해서도 동작하도록 처리하고 있다.&lt;br /&gt;더 범용적인 코드라고 보면 된다.&lt;br /&gt;나도 두고두고 봐야 하니까 코드를 붙여넣어 둔다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/50902067/how-to-import-the-tensorflow-lite-interpreter-in-python&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;How to import the tensorflow lite interpreter in Python?&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;test_tflite_model_by_stack_overflow&lt;/span&gt;(tflite_path):&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# Load TFLite model and allocate tensors.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;interpreter = tf.contrib.lite.Interpreter(&lt;span style=&quot;color:#aa4926;&quot;&gt;model_path&lt;/span&gt;=tflite_path)&lt;br /&gt;    interpreter.allocate_tensors()&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# Get input and output tensors.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;input_details = interpreter.get_input_details()&lt;br /&gt;    output_details = interpreter.get_output_details()&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# Test model on random input data.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;input_shape = input_details[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6a8759;&quot;&gt;'shape'&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;# 사진 경로 매개 변수는 없다. 난수로 만들면 되니까. 문법적으로 에러 나지 않는 것만 확인하면 된다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;input_data = np.array(np.random.random_sample(input_shape)&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#aa4926;&quot;&gt;dtype&lt;/span&gt;=np.float32)&lt;br /&gt;    interpreter.set_tensor(input_details[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6a8759;&quot;&gt;'index'&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;input_data)&lt;br /&gt;&lt;br /&gt;    interpreter.invoke()&lt;br /&gt;    output_data = interpreter.get_tensor(output_details[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6a8759;&quot;&gt;'index'&lt;/span&gt;])&lt;br /&gt;    &lt;span style=&quot;color:#8888c6;&quot;&gt;print&lt;/span&gt;(output_data)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>텐서플로 라이트</category>
      <category>텐서플로 라이트</category>
      <category>플러터</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/155</guid>
      <comments>https://pythonkim.tistory.com/155#entry155comment</comments>
      <pubDate>Sun, 19 May 2019 12:28:43 +0900</pubDate>
    </item>
    <item>
      <title>13. 플러터 : 개와 고양이 사진 분류 (케라스) (4)</title>
      <link>https://pythonkim.tistory.com/154</link>
      <description>&lt;p&gt;이번 프로젝트의 마지막인 안드로이드 부분만 남았다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6번&lt;/b&gt;&lt;br /&gt;파이썬으로 작업한 딥러닝 모델 파일을 추가한다.&lt;br /&gt;MainActivity.java 파일이 포함된 java 프로젝트와 같은 위치에 assets 폴더를 생성하고&lt;br /&gt;cats_and_dogs.tflite 모델 파일을 붙여넣는다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 437px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995ACB395CDD03041E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995ACB395CDD03041E&quot; width=&quot;437&quot; height=&quot;526&quot; filename=&quot;catdog_2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;7번&lt;/b&gt;&lt;br /&gt;gradle 파일을 수정한다.&lt;br /&gt;위의 그림에서 profile 폴더 바로 아래 있는 파일이다.&lt;br /&gt;같은 이름이 두 개 있어서 헷갈리기 딱 좋다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;android {&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 추가한 부분&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;aaptOptions {&lt;br /&gt;        noCompress &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;tflite&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;dependencies {&lt;br /&gt;    testImplementation &lt;span style=&quot;color:#6a8759;&quot;&gt;'junit:junit:4.12'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;androidTestImplementation &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.android.support.test:runner:1.0.2'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;androidTestImplementation &lt;span style=&quot;color:#6a8759;&quot;&gt;'com.android.support.test.espresso:espresso-core:3.0.2'&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 추가한 부분&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;implementation &lt;span style=&quot;color:#6a8759;&quot;&gt;'org.tensorflow:tensorflow-lite:+'&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;8번&lt;/b&gt;&lt;br /&gt;경로 수신 및 모델 연동 코드를 구현한다.&lt;br /&gt;MainActivity.java 파일을 열고 아래 코드를 붙여넣는다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;package &lt;/span&gt;tflite.com.catdog.flutter_catdog&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.os.Bundle&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.graphics.Bitmap&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.graphics.BitmapFactory&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.app.Activity&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.content.res.AssetFileDescriptor&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.util.Log&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.io.FileInputStream&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.nio.MappedByteBuffer&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.nio.channels.FileChannel&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.io.IOException&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.nio.ByteBuffer&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.nio.ByteOrder&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;org.tensorflow.lite.Interpreter&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 기본적으로 포함되어 있는 모듈&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.app.FlutterActivity&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.plugins.GeneratedPluginRegistrant&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// MethodChannel 관련 모듈 (추가해야 함)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.plugin.common.MethodChannel&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.plugin.common.MethodChannel.MethodCallHandler&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.plugin.common.MethodChannel.Result&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;io.flutter.plugin.common.MethodCall&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;MainActivity &lt;span style=&quot;color:#cc7832;&quot;&gt;extends &lt;/span&gt;FlutterActivity {&lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 채널 문자열. 플러터에 정의한 것과 동일해야 한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private static final &lt;/span&gt;String mChannel = &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;catdog/predict&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;@Override&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;protected void &lt;/span&gt;onCreate(Bundle savedInstanceState) {&lt;br /&gt;        &lt;span style=&quot;color:#808080;&quot;&gt;// 빌트인 코드&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;super&lt;/span&gt;.onCreate(savedInstanceState)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;GeneratedPluginRegistrant.registerWith(&lt;span style=&quot;color:#cc7832;&quot;&gt;this&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 추가한 함수.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MethodChannel(getFlutterView()&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;mChannel).setMethodCallHandler(&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;MethodCallHandler() {&lt;br /&gt;                    @Override&lt;br /&gt;                    &lt;span style=&quot;color:#cc7832;&quot;&gt;public void &lt;/span&gt;onMethodCall(MethodCall call&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Result result) {&lt;br /&gt;                        &lt;span style=&quot;color:#808080;&quot;&gt;// 각각의 메소드를 switch로 분류. 아이폰에서는 else if 사용.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;switch &lt;/span&gt;(call.method) {&lt;br /&gt;                            &lt;span style=&quot;color:#cc7832;&quot;&gt;case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;predictImage&quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style=&quot;color:#808080;&quot;&gt;// Map&amp;lt;String, String&amp;gt; args = (HashMap) call.arguments;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                // String path = args.get(&quot;path&quot;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                &lt;/span&gt;String path = call.argument(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;path&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                final &lt;/span&gt;Bitmap bitmapRaw = BitmapFactory.decodeFile(path)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                int &lt;/span&gt;cx = &lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cy = &lt;span style=&quot;color:#6897bb;&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;Bitmap bitmap = Bitmap.createScaledBitmap(bitmapRaw&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cy&lt;span style=&quot;color:#cc7832;&quot;&gt;, false&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                int&lt;/span&gt;[] pixels = &lt;span style=&quot;color:#cc7832;&quot;&gt;new int&lt;/span&gt;[cx * cy]&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;bitmap.getPixels(pixels&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cy)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 두 가지 방법 모두 동작. 입력 텐서는 자료형을 내부적으로 재해석한다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                // float[][][][] input_img = getInputImage_1(pixels, cx, cy);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                &lt;/span&gt;ByteBuffer input_img = getInputImage_2(pixels&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;cy)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// float[] input_img = getInputImage_3(pixels, cx, cy);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                                &lt;/span&gt;Interpreter tf_lite = getTfliteInterpreter(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;cats_and_dogs.tflite&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                float&lt;/span&gt;[][] pred = &lt;span style=&quot;color:#cc7832;&quot;&gt;new float&lt;/span&gt;[&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;][&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;tf_lite.run(input_img&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;pred)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                final &lt;/span&gt;String predText = String.format(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;%f&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;pred[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;])&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;Log.d(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;예측&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;predText)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;result.success(predText)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            default&lt;/span&gt;:&lt;br /&gt;                                result.notImplemented()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        &lt;/span&gt;}&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;        )&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 입력 이미지와 동일한 형태의 배열 사용&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private float&lt;/span&gt;[][][][] getInputImage_1(&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;[] pixels&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cy) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;[][][][] input_img = &lt;span style=&quot;color:#cc7832;&quot;&gt;new float&lt;/span&gt;[&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;][cx][cy][&lt;span style=&quot;color:#6897bb;&quot;&gt;3&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        int &lt;/span&gt;k = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        for &lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;y = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;y &amp;lt; cy&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;y++) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;for &lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;x = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;x &amp;lt; cx&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;x++) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;pixel = pixels[k++]&lt;span style=&quot;color:#cc7832;&quot;&gt;;        &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// ARGB : ff4e2a2a&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;                &lt;/span&gt;input_img[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][y][x][&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;16&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;input_img[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][y][x][&lt;span style=&quot;color:#6897bb;&quot;&gt;1&lt;/span&gt;] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;input_img[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;][y][x][&lt;span style=&quot;color:#6897bb;&quot;&gt;2&lt;/span&gt;] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;input_img&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 다루기 편한 1차원 배열 사용&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;ByteBuffer getInputImage_2(&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;[] pixels&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cy) {&lt;br /&gt;        ByteBuffer input_img = ByteBuffer.allocateDirect(cx * cy * &lt;span style=&quot;color:#6897bb;&quot;&gt;3 &lt;/span&gt;* &lt;span style=&quot;color:#6897bb;&quot;&gt;4&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;input_img.order(ByteOrder.nativeOrder())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        for &lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;i = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;i &amp;lt; cx * cy&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;i++) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;pixel = pixels[i]&lt;span style=&quot;color:#cc7832;&quot;&gt;;        &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// ARGB : ff4e2a2a&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;input_img.putFloat(((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;16&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;input_img.putFloat(((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;input_img.putFloat(((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;input_img&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 될 것 같지만 되지 않는 코드&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private float&lt;/span&gt;[] getInputImage_3(&lt;span style=&quot;color:#cc7832;&quot;&gt;int&lt;/span&gt;[] pixels&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cx&lt;span style=&quot;color:#cc7832;&quot;&gt;, int &lt;/span&gt;cy) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;[] input_img = &lt;span style=&quot;color:#cc7832;&quot;&gt;new float&lt;/span&gt;[cx * cy * &lt;span style=&quot;color:#6897bb;&quot;&gt;3 &lt;/span&gt;* &lt;span style=&quot;color:#6897bb;&quot;&gt;4&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        int &lt;/span&gt;k = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        for &lt;/span&gt;(&lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;i = &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;i &amp;lt; cx * cy&lt;span style=&quot;color:#cc7832;&quot;&gt;; &lt;/span&gt;i++) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;pixel = pixels[i]&lt;span style=&quot;color:#cc7832;&quot;&gt;;        &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// ARGB : ff4e2a2a&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;input_img[k++] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;16&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;input_img[k++] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;8&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;input_img[k++] = ((pixel &amp;gt;&amp;gt; &lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;) &amp;amp; &lt;span style=&quot;color:#6897bb;&quot;&gt;0xff&lt;/span&gt;) / (&lt;span style=&quot;color:#cc7832;&quot;&gt;float&lt;/span&gt;) &lt;span style=&quot;color:#6897bb;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;input_img&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 모델 파일 인터프리터를 생성하는 공통 함수&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    // loadModelFile 함수에 예외가 포함되어 있기 때문에 반드시 try, catch 블록이 필요하다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;Interpreter getTfliteInterpreter(String modelPath) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;try &lt;/span&gt;{&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;return new &lt;/span&gt;Interpreter(loadModelFile(MainActivity.&lt;span style=&quot;color:#cc7832;&quot;&gt;this, &lt;/span&gt;modelPath))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;catch &lt;/span&gt;(Exception e) {&lt;br /&gt;            e.printStackTrace()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 모델을 읽어오는 함수로, 텐서플로 라이트 홈페이지에 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    // MappedByteBuffer 바이트 버퍼를 Interpreter 객체에 전달하면 모델 해석을 할 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;private &lt;/span&gt;MappedByteBuffer loadModelFile(Activity activity&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String modelPath) &lt;span style=&quot;color:#cc7832;&quot;&gt;throws &lt;/span&gt;IOException {&lt;br /&gt;        AssetFileDescriptor fileDescriptor = activity.getAssets().openFd(modelPath)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;FileInputStream inputStream = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;FileInputStream(fileDescriptor.getFileDescriptor())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;FileChannel fileChannel = inputStream.getChannel()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        long &lt;/span&gt;startOffset = fileDescriptor.getStartOffset()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        long &lt;/span&gt;declaredLength = fileDescriptor.getDeclaredLength()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        return &lt;/span&gt;fileChannel.map(FileChannel.MapMode.READ_ONLY&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;startOffset&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;declaredLength)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;코드를 교체하고 나서 문제가 발생했다면&lt;br /&gt;오른쪽 상단에 있는 Setup SDK 메뉴를 선택해서 해결해야 한다.&lt;br /&gt;아래와 같은 화면이 뜨고 적당한 버전을 선택해서 연결한다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 371px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992AC04D5CDD05790A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992AC04D5CDD05790A&quot; width=&quot;371&quot; height=&quot;159&quot; filename=&quot;catdog_4.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;9번&lt;/b&gt;&lt;br /&gt;개와 고양이 사진을 에뮬레이터로 찍기는 어렵다.&lt;br /&gt;안드로이드 폰에 올려서 결과를 볼 수도 있겠지만&lt;br /&gt;여기서는 에뮬레이터로 복사해서 가져다 쓰도록 한다.&lt;/p&gt;
&lt;p&gt;[View - Tool Windows - Device File Explorer] 메뉴를 선택한다.&lt;br /&gt;[sdcard - Download] 폴더에서 마우스 오른쪽 버튼을 눌러 업로드를 선택한다.&lt;br /&gt;개와 고양이 폴더에서 각각 2개씩 추가했다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 507px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991F92495CDD076D1A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991F92495CDD076D1A&quot; width=&quot;507&quot; height=&quot;518&quot; filename=&quot;catdog_5.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;4장의 사진을 업로드하고 나면 아래와 같이 확인할 수 있다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 300px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99C689365CE0CA2C1E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99C689365CE0CA2C1E&quot; width=&quot;300&quot; height=&quot;600&quot; filename=&quot;final_2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;이제 모든게 끝났다.&lt;br /&gt;완성을 하지 못해서 계속 비공개로 유지했었다.&lt;br /&gt;마지막으로 우재 폰을 사용해서 카메라 메뉴도 확인했다.&lt;br /&gt;모니터에 있는 개와 고양이 사진을 얼마나 잘 분류하던지..&lt;br /&gt;감동이었다.&lt;/p&gt;
&lt;p&gt;일요일 12시 20분.&lt;br /&gt;우재는 곤충 박사님이 부탁한 프로젝트를 하고 있고&lt;br /&gt;서진이는 한동안 잊고 살았던 파이썬을 다시 공부하고 있다.&lt;br /&gt;모두 흥미를 느끼고 있어 좋다.&lt;br /&gt;일요일이 일요일이다.&lt;br /&gt;다만 많이 시끄럽다. ^^&lt;/p&gt;</description>
      <category>텐서플로 라이트</category>
      <category>텐서플로 라이트</category>
      <category>플러터</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/154</guid>
      <comments>https://pythonkim.tistory.com/154#entry154comment</comments>
      <pubDate>Thu, 16 May 2019 15:08:12 +0900</pubDate>
    </item>
    <item>
      <title>12. 플러터 : 개와 고양이 사진 분류 (케라스) (3)</title>
      <link>https://pythonkim.tistory.com/153</link>
      <description>&lt;p&gt;모델 파일은 생성했고&lt;br /&gt;이제 스마트폰에 올릴 코드를 구성하면 된다.&lt;br /&gt;먼저 플러터 코드를 구성하고 다음 글에서 안드로이드 코드를 구현한다.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;&lt;b&gt;3번&lt;/b&gt;&lt;br /&gt;
안드로이드 스튜디오에서 flutter_catdog으로 플러터 프로젝트를 생성한다.&lt;br /&gt;프로젝트 옵션에서는 지금처럼 코틀린 사용은 표시하지 않는다. ^^&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;&lt;b&gt;4번&lt;/b&gt;&lt;br /&gt;
pubspec.yaml 파일을 열고 이미지 피커 모듈을 추가한다.&lt;br /&gt;잊지 말고, 상단에 있는 Packages upgrade 메뉴를 눌러 업그레이드를 진행한다.&lt;/p&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;dependencies&lt;/span&gt;:&lt;br /&gt;  &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;flutter&lt;/span&gt;:&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;sdk&lt;/span&gt;: flutter&lt;br /&gt;&lt;br /&gt;  &lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt;# The following adds the Cupertino Icons font to your application.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt;  # Use with the CupertinoIcons class for iOS style icons.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#629755;font-style:italic;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;cupertino_icons&lt;/span&gt;: ^0.1.2&lt;br /&gt;  &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;image_picker&lt;/span&gt;:&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;5번&lt;/b&gt;&lt;br /&gt;안드로이드와 연동하는 코드를 구현한다.&lt;br /&gt;사진과 카메라 중에서 선택할 수 있고&lt;br /&gt;선택하거나 촬영한 사진으로부터 경로를 가져와서 안드로이드에 전달한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'Menlo';font-size:9.8pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;import &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'dart:io'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;import &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;import &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'package:flutter/services.dart'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;import &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;'package:image_picker/image_picker.dart'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;  &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 이미지 피커&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;class &lt;/span&gt;CatDogNets &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;extends &lt;/span&gt;StatefulWidget {&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;CatDogNetsState &lt;span style=&quot;color:#ffc66d;&quot;&gt;createState&lt;/span&gt;() =&amp;gt; &lt;span style=&quot;color:#ffc66d;&quot;&gt;CatDogNetsState&lt;/span&gt;()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;class &lt;/span&gt;CatDogNetsState &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;extends &lt;/span&gt;State&amp;lt;CatDogNets&amp;gt; {&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;static const &lt;/span&gt;MethodChannel &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;mMethodChannel &lt;/span&gt;= &lt;span style=&quot;color:#ffc66d;&quot;&gt;MethodChannel&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;'catdog/predict'&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;&quot;&gt;mResult &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;'No Photo!'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;   &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 예측 결과를 수신할 문자열&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;File &lt;span style=&quot;color:#9876aa;&quot;&gt;mPhoto&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;                    &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 선택 또는 촬영한 사진. ImagePicker 반환값&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@override&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;    &lt;/span&gt;Widget &lt;span style=&quot;color:#ffc66d;&quot;&gt;build&lt;/span&gt;(BuildContext context) {&lt;br /&gt;        Widget photo = (&lt;span style=&quot;color:#9876aa;&quot;&gt;mPhoto &lt;/span&gt;!= &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;null&lt;/span&gt;) ? &lt;span style=&quot;color:#ffc66d;&quot;&gt;Image&lt;/span&gt;.&lt;span style=&quot;color:#ffc66d;&quot;&gt;file&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;mPhoto&lt;/span&gt;) : &lt;span style=&quot;color:#ffc66d;&quot;&gt;Placeholder&lt;/span&gt;()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;Material&lt;/span&gt;(&lt;br /&gt;            child: &lt;span style=&quot;color:#ffc66d;&quot;&gt;Column&lt;/span&gt;(&lt;br /&gt;                children: &amp;lt;Widget&amp;gt;[&lt;br /&gt;                    &lt;span style=&quot;color:#ffc66d;&quot;&gt;Expanded&lt;/span&gt;(&lt;br /&gt;                        child: &lt;span style=&quot;color:#ffc66d;&quot;&gt;Center&lt;/span&gt;(child: photo)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;Row&lt;/span&gt;(&lt;br /&gt;                        children: &amp;lt;Widget&amp;gt;[&lt;span style=&quot;color:#ffc66d;&quot;&gt;Text&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;&quot;&gt;mResult&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;style: &lt;span style=&quot;color:#ffc66d;&quot;&gt;TextStyle&lt;/span&gt;(fontSize: &lt;span style=&quot;color:#6897bb;&quot;&gt;23&lt;/span&gt;))]&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        &lt;/span&gt;mainAxisAlignment: MainAxisAlignment.&lt;span style=&quot;color:#9876aa;&quot;&gt;spaceEvenly&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;Row&lt;/span&gt;(&lt;br /&gt;                        children: &amp;lt;Widget&amp;gt;[&lt;br /&gt;                            &lt;span style=&quot;color:#ffc66d;&quot;&gt;RaisedButton&lt;/span&gt;(&lt;br /&gt;                                child: &lt;span style=&quot;color:#ffc66d;&quot;&gt;Text&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;'사진'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;style: &lt;span style=&quot;color:#ffc66d;&quot;&gt;TextStyle&lt;/span&gt;(fontSize: &lt;span style=&quot;color:#6897bb;&quot;&gt;23&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;onPressed: () =&amp;gt; onPhoto(ImageSource.&lt;span style=&quot;color:#9876aa;&quot;&gt;gallery&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;RaisedButton&lt;/span&gt;(&lt;br /&gt;                                child: &lt;span style=&quot;color:#ffc66d;&quot;&gt;Text&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;'카메라'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;style: &lt;span style=&quot;color:#ffc66d;&quot;&gt;TextStyle&lt;/span&gt;(fontSize: &lt;span style=&quot;color:#6897bb;&quot;&gt;23&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                                &lt;/span&gt;onPressed: () =&amp;gt; onPhoto(ImageSource.&lt;span style=&quot;color:#9876aa;&quot;&gt;camera&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                            &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        &lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                        &lt;/span&gt;mainAxisAlignment: MainAxisAlignment.&lt;span style=&quot;color:#9876aa;&quot;&gt;spaceEvenly&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    &lt;/span&gt;)&lt;br /&gt;                ]&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;mainAxisAlignment: MainAxisAlignment.&lt;span style=&quot;color:#9876aa;&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color:#808080;&quot;&gt;// 앨범과 카메라 양쪽에서 호출. ImageSource.gallery와 ImageSource.camera 두 가지밖에 없다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;onPhoto&lt;/span&gt;(ImageSource source) &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;async &lt;/span&gt;{&lt;br /&gt;        &lt;span style=&quot;color:#9876aa;&quot;&gt;mPhoto &lt;/span&gt;= &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;await &lt;/span&gt;ImagePicker.&lt;span style=&quot;color:#ffc66d;font-style:italic;&quot;&gt;pickImage&lt;/span&gt;(source: source)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;try &lt;/span&gt;{&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;var &lt;/span&gt;photoPath = &amp;lt;String&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String&amp;gt;{&lt;span style=&quot;color:#6a8759;&quot;&gt;'path'&lt;/span&gt;: &lt;span style=&quot;color:#9876aa;&quot;&gt;mPhoto&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;&quot;&gt;path&lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;String received = &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;await &lt;/span&gt;&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;mMethodChannel&lt;/span&gt;.invokeMethod(&lt;span style=&quot;color:#6a8759;&quot;&gt;'predictImage'&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;photoPath)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;// 안드로이드로부터 결과 수신하고, 선택한 사진으로 변경&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#808080;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color:#9876aa;&quot;&gt;mResult &lt;/span&gt;= received&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;setState(() =&amp;gt; {})&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;on &lt;/span&gt;PlatformException {}&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color:#cc7832;font-weight:bold;&quot;&gt;void &lt;/span&gt;&lt;span style=&quot;color:#ffc66d;&quot;&gt;main&lt;/span&gt;() {&lt;br /&gt;    runApp(&lt;span style=&quot;color:#ffc66d;&quot;&gt;MaterialApp&lt;/span&gt;(home: &lt;span style=&quot;color:#ffc66d;&quot;&gt;CatDogNets&lt;/span&gt;()))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>텐서플로 라이트</category>
      <category>텐서플로 라이트</category>
      <category>플러터</category>
      <author>사과쿵</author>
      <guid isPermaLink="true">https://pythonkim.tistory.com/153</guid>
      <comments>https://pythonkim.tistory.com/153#entry153comment</comments>
      <pubDate>Thu, 16 May 2019 14:27:39 +0900</pubDate>
    </item>
  </channel>
</rss>