ホーム » Keras » TensorFlow 2.0 : ガイド : Keras :- Keras でリカレント・ニューラルネットワーク (RNN)

TensorFlow 2.0 : ガイド : Keras :- Keras でリカレント・ニューラルネットワーク (RNN)

TensorFlow 2.0 : ガイド : Keras :- Keras でリカレント・ニューラルネットワーク (RNN) (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/26/2019

* 本ページは、TensorFlow org サイトの Guide – Keras の以下のページを翻訳した上で
適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

ガイド : Keras :- Keras でリカレント・ニューラルネットワーク (RNN)

リカレント・ニューラルネットワーク (RNN) は、時系列や自然言語のようなシークエンス・データをモデル化するためのパワフルなニューラルネットワークのクラスです。

模式的には (= schematically)、RNN 層はシークエンスの時間ステップに渡り反復するために for ループを使用し、一方でそれがそこまでに見た時間ステップについての情報をエンコードする内部状態を保持します。

Keras RNN API は以下に焦点を絞って設計されています :

  • 利用の容易さ: 組込み tf.keras.layers.RNN, tf.keras.layers.LSTM, tf.keras.layers.GRU 層は難しい configuration 選択を行わなければならないことなくリカレント・モデルを素早く構築することを可能にします。
  • カスタマイズの容易さ: カスタム動作を持つ貴方自身の RNN セル層 (for ループの内側部) を定義し、そしてそれを一般的な tf.keras.layers.RNN 層 (for ループ自身) で使用することもできます。これは異なる研究アイデアを最小限のコードで柔軟な方法で素早くプロトタイピングすることを可能にします。

 

セットアップ

from __future__ import absolute_import, division, print_function, unicode_literals

import collections
import matplotlib.pyplot as plt
import numpy as np

import tensorflow as tf

from tensorflow.keras import layers

 

単純なモデルを構築する

Keras には 3 つの組込み RNN があります :

  1. tf.keras.layers.SimpleRNN, 完全結合 RNN そこでは前の時間ステップからの出力は次の時間ステップに供給されます。
  2. tf.keras.layers.GRU, 最初に Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation 内で提案されました。
  3. tf.keras.layers.LSTM, 最初に Long Short-Term Memory で提案されました。

2015 年初期に、Keras は LSTM と GRU の最初の再利用可能なオープンソース Python 実装を持ちました。

ここに Sequential モデルの単純なサンプルがあります、これは整数のシークエンスを処理し、各整数を 64-次元ベクトルに埋め込み、それから LSTM 層を使用してベクトルのシークエンスを処理します。

model = tf.keras.Sequential()
# Add an Embedding layer expecting input vocab of size 1000, and
# output embedding dimension of size 64.
model.add(layers.Embedding(input_dim=1000, output_dim=64))

# Add a LSTM layer with 128 internal units.
model.add(layers.LSTM(128))

# Add a Dense layer with 10 units and softmax activation.
model.add(layers.Dense(10, activation='softmax'))

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 64)          64000     
_________________________________________________________________
lstm (LSTM)                  (None, 128)               98816     
_________________________________________________________________
dense (Dense)                (None, 10)                1290      
=================================================================
Total params: 164,106
Trainable params: 164,106
Non-trainable params: 0

 

出力と状態

デフォルトでは、RNN 層の出力はサンプル毎に単一のベクトルを含みます。このベクトルは最後の時間ステップに対応する RNN セル出力で、入力シークエンス全体についての情報を含みます。この出力の shape は (batch_size, units) です、ここで units は層のコンストラクタに渡される units 引数に対応します。

RNN 層はまた各サンプルに対する出力の全体のシークエンス (1 ベクトル per 時間ステップ per サンプル) を返すこともできます、return_sequences=True を設定する場合。この出力の shape は (batch_size, timesteps, units) です。

model = tf.keras.Sequential()
model.add(layers.Embedding(input_dim=1000, output_dim=64))

# The output of GRU will be a 3D tensor of shape (batch_size, timesteps, 256)
model.add(layers.GRU(256, return_sequences=True))

# The output of SimpleRNN will be a 2D tensor of shape (batch_size, 128)
model.add(layers.SimpleRNN(128))

model.add(layers.Dense(10, activation='softmax'))

model.summary() 
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, None, 64)          64000     
_________________________________________________________________
gru (GRU)                    (None, None, 256)         247296    
_________________________________________________________________
simple_rnn (SimpleRNN)       (None, 128)               49280     
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 361,866
Trainable params: 361,866
Non-trainable params: 0
_________________________________________________________________

加えて、RNN 層はその最終内部状態を返すことができます。返された状態は後で RNN 実行を再開するためにか、もう一つの RNN を初期化する ために利用できます。この設定は一般にエンコーダ・デコーダ sequence-to-sequence モデルで使用され、そこではエンコーダ最終状態はデコーダの初期状態として使用されます。

RNN 層をその内部状態を返すように configure するには、層を作成するとき return_state パラメータを True に設定します。LSTM は 2 状態 tensor を持ちますが、GRU は一つだけを持つことに注意してください。

層の初期状態を configure するためには、単に層を追加のキーワード引数 initial_state で呼び出します。状態の shape は下のサンプルのように、層の unit サイズに適合する必要があります。

encoder_vocab = 1000
decoder_vocab = 2000

encoder_input = layers.Input(shape=(None, ))
encoder_embedded = layers.Embedding(input_dim=encoder_vocab, output_dim=64)(encoder_input)

# Return states in addition to output
output, state_h, state_c = layers.LSTM(
    64, return_state=True, name='encoder')(encoder_embedded)
encoder_state = [state_h, state_c]

decoder_input = layers.Input(shape=(None, ))
decoder_embedded = layers.Embedding(input_dim=decoder_vocab, output_dim=64)(decoder_input)

# Pass the 2 states to a new LSTM layer, as initial state
decoder_output = layers.LSTM(
    64, name='decoder')(decoder_embedded, initial_state=encoder_state)
output = layers.Dense(10, activation='softmax')(decoder_output)

model = tf.keras.Model([encoder_input, decoder_input], output)
model.summary()
Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, None)]       0                                            
__________________________________________________________________________________________________
input_2 (InputLayer)            [(None, None)]       0                                            
__________________________________________________________________________________________________
embedding_2 (Embedding)         (None, None, 64)     64000       input_1[0][0]                    
__________________________________________________________________________________________________
embedding_3 (Embedding)         (None, None, 64)     128000      input_2[0][0]                    
__________________________________________________________________________________________________
encoder (LSTM)                  [(None, 64), (None,  33024       embedding_2[0][0]                
__________________________________________________________________________________________________
decoder (LSTM)                  (None, 64)           33024       embedding_3[0][0]                
                                                                 encoder[0][1]                    
                                                                 encoder[0][2]                    
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 10)           650         decoder[0][0]                    
==================================================================================================
Total params: 258,698
Trainable params: 258,698
Non-trainable params: 0
__________________________________________________________________________________________________

 

RNN 層と RNN セル

組込み RNN 層に加えて、RNN API はまたセルレベル API も提供します。入力シークエンスのバッチ全体を処理する RNN 層と違い、RNN セルは単一の時間ステップだけを処理します。

セルは RNN 層の for ループの内側にあります。tf.keras.layers.RNN 層の内側でのセルのラッピングはシークエンスのバッチを処理できる層を与えます, e.g. RNN(LSTMCell(10))。

数学的には、RNN(LSTMCell(10)) は LSTM (10) と同じ結果を生成します。実際に、TF v1.x のこの層の実装は単に対応する RNN セルを作成してそれを RNN 層でラッピングしていました。けれども組込み GRU と LSTM 層の使用は CuDNN の使用を有効にしますのでより良いパフォーマンスを見るかもしれません。

3 つの組込み RNN セルがあり、それらの各々は適合する RNN 層に対応します。

セル抽象は、一般的な tf.keras.layers.RNN クラスと一緒に、貴方の研究のためにカスタム RNN アーキテクチャを実装することを非常に容易にします。

 

交差バッチ statefulness

非常に長いシークエンス (多分無限大) を処理するとき、交差バッチ statefulness のパターンを使用することを望むかもしれません。

通常は、RNN 層の内部状態はそれが新しいバッチを見るたびにリセットされます (i.e. 層により見られる総てのサンプルは過去 (のもの) から独立的であると仮定されています)。層は与えられたサンプルを処理する間、状態を維持するだけです。

けれども非常に長いシークエンスを持つ場合、それらをより短いシークエンスに分解して (層の状態をリセットすることなく) それらの短いシークエンスを RNN 層にシーケンシャルに供給することは有用です。このようにして、層は、それが一度に一つの部分シークエンスを見ているだけですが、シークエンス全体についての情報を保持できます。

コンストラクタで stateful=True を設定することによりこれを行なうことができます。

もしシークエンス s = [t0, t1, … t1546, t1547] を持つ場合、それを例えば次のように分割できます :

s1 = [t0, t1, ... t100]
s2 = [t101, ... t201]
...
s16 = [t1501, ... t1547]

それからそれを次を通して処理するでしょう :

lstm_layer = layers.LSTM(64, stateful=True)
for s in sub_sequences:
  output = lstm_layer(s)

状態をクリアすることを望むとき、layer.reset_states() を使用できます。

Note: このセットアップでは、与えられたバッチ内のサンプル i は前のバッチ内のサンプル i の続きであることが仮定されています。これは総てのバッチはサンプルの同じ数 (バッチサイズ) を含むべきであることを意味します。例えば、もしバッチが [sequence_A_from_t0_to_t100, sequence_B_from_t0_to_t100] を含む場合、次のバッチは [sequence_A_from_t101_to_t200, sequence_B_from_t101_to_t200] を含むべきです。

ここに完全なサンプルがあります :

paragraph1 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph2 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph3 = np.random.random((20, 10, 50)).astype(np.float32)

lstm_layer = layers.LSTM(64, stateful=True)
output = lstm_layer(paragraph1)
output = lstm_layer(paragraph2)
output = lstm_layer(paragraph3)

# reset_states() will reset the cached state to the original initial_state.
# If no initial_state was provided, zero-states will be used by default.
lstm_layer.reset_states()

 

双方向 RNN

時系列以外のシークエンス (e.g. テキスト) については、RNN モデルはそれが最初から最後までシークエンスを処理するだけでなく反対にも処理する場合により良く遂行できることが多いです。例えば、センテンスの次の単語を予測するためには、その前に来る単語だけでなく、単語回りのコンテキストを持つことがしばしば有用です。

Keras はそのような双方向 RNN を構築するための容易な API を提供します : tf.keras.layers.Bidirectional ラッパーです。

model = tf.keras.Sequential()

model.add(layers.Bidirectional(layers.LSTM(64, return_sequences=True), 
                               input_shape=(5, 10)))
model.add(layers.Bidirectional(layers.LSTM(32)))
model.add(layers.Dense(10, activation='softmax'))

model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
bidirectional (Bidirectional (None, 5, 128)            38400     
_________________________________________________________________
bidirectional_1 (Bidirection (None, 64)                41216     
_________________________________________________________________
dense_3 (Dense)              (None, 10)                650       
=================================================================
Total params: 80,266
Trainable params: 80,266
Non-trainable params: 0
_________________________________________________________________

内部的には、Bidirectional は渡された RNN 層をコピーして新たにコピーされた層の go_backwards フィールドを反転します、その結果それは入力を反対の順序で処理します。

Bidirectional RNN の出力はデフォルトでは forward 層出力と backward 層出力の合計です。異なるマージ動作, e.g. 連結を必要とする場合には、Bidirectional ラッパー・コンストラクタで merge_mode パラメータを変更します。Bidirectional についてのより詳細は、API doc を確認してください。

 

パフォーマンス最適化と TensorFlow 2.0 の CuDNN カーネル

TensorFlow 2.0 では、組込み LSTM と GRU 層は GPU が利用可能なときデフォルトで CuDNN カーネルを活用するために更新されました。この変更で、以前の keras.layers.CuDNNLSTM/CuDNNGRU 層は deprecated となり、そして貴方はモデルをそれが動作するハードウェアについて心配することなく構築できます。

CuDNN カーネルはある仮定で構築されますので、これは組込み LSTM や GRU 層のデフォルトを変更する場合、層は CuDNN カーネルを使用できないことを意味します。例えば :

  • 活性化関数を tanh から他のものに変更する。
  • recurrent_activation 関数を sigmoid から他のものに変更する。
  • recurrent_dropout > 0 を使用する。
  • unroll を True に設定する、これは LSTM/GRU に内側の tf.while_loop を unrolled for ループに分解します。
  • use_bias を False に設定する。
  • 入力データが厳密に右パディングされないときマスキングを使用する (マスクが厳密に右パディングされたデータに対応する場合、CuDNN は依然として使用できます。これは最も一般的なケースです)。

制約の詳細なリストについては、LSTMGRU 層のためのドキュメントを見てください。

 

利用可能なとき CuDNN カーネルを使用する

パフォーマンスの違いを実演するために単純な LSTM モデルを構築しましょう。

入力シークエンスとしてMNIST 数字の行のシークエンスを使用します (ピクセルの各行を時間ステップとして扱います)、そして数字のラベルを予測します。

batch_size = 64
# Each MNIST image batch is a tensor of shape (batch_size, 28, 28).
# Each input sequence will be of size (28, 28) (height is treated like time).
input_dim = 28

units = 64
output_size = 10  # labels are from 0 to 9

# Build the RNN model
def build_model(allow_cudnn_kernel=True):
  # CuDNN is only available at the layer level, and not at the cell level.
  # This means `LSTM(units)` will use the CuDNN kernel,
  # while RNN(LSTMCell(units)) will run on non-CuDNN kernel.
  if allow_cudnn_kernel:
    # The LSTM layer with default options uses CuDNN.
    lstm_layer = tf.keras.layers.LSTM(units, input_shape=(None, input_dim))
  else:
    # Wrapping a LSTMCell in a RNN layer will not use CuDNN.
    lstm_layer = tf.keras.layers.RNN(
        tf.keras.layers.LSTMCell(units),
        input_shape=(None, input_dim))
  model = tf.keras.models.Sequential([
      lstm_layer,
      tf.keras.layers.BatchNormalization(),
      tf.keras.layers.Dense(output_size, activation='softmax')]
  )
  return model

 

MNIST データセットをロードする

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
sample, sample_label = x_train[0], y_train[0]

 

モデルインスタンスを作成してそれをコンパイルする

モデルのための損失関数として sparse_categorical_crossentropy を選択します。モデルの出力は [batch_size, 10] の shape を持ちます。モデルのためのターゲットは整数ベクトルで、整数の各々は 0 から 9 の範囲にあります。

model = build_model(allow_cudnn_kernel=True)

model.compile(loss='sparse_categorical_crossentropy', 
              optimizer='sgd',
              metrics=['accuracy'])
model.fit(x_train, y_train,
          validation_data=(x_test, y_test),
          batch_size=batch_size,
          epochs=5)
Train on 60000 samples, validate on 10000 samples
Epoch 1/5
60000/60000 [==============================] - 8s 126us/sample - loss: 0.9247 - accuracy: 0.7083 - val_loss: 0.5664 - val_accuracy: 0.8170
Epoch 2/5
60000/60000 [==============================] - 5s 85us/sample - loss: 0.3930 - accuracy: 0.8821 - val_loss: 0.3145 - val_accuracy: 0.9002
Epoch 3/5
60000/60000 [==============================] - 5s 85us/sample - loss: 0.2515 - accuracy: 0.9241 - val_loss: 0.2888 - val_accuracy: 0.9070
Epoch 4/5
60000/60000 [==============================] - 5s 86us/sample - loss: 0.1961 - accuracy: 0.9407 - val_loss: 0.1784 - val_accuracy: 0.9428
Epoch 5/5
60000/60000 [==============================] - 6s 93us/sample - loss: 0.1649 - accuracy: 0.9510 - val_loss: 0.1326 - val_accuracy: 0.9573

<tensorflow.python.keras.callbacks.History at 0x7f6a980abb38>

 

新しいモデルを CuDNN カーネルなしで構築する

slow_model = build_model(allow_cudnn_kernel=False)
slow_model.set_weights(model.get_weights())
slow_model.compile(loss='sparse_categorical_crossentropy', 
                   optimizer='sgd', 
                   metrics=['accuracy'])
slow_model.fit(x_train, y_train, 
               validation_data=(x_test, y_test), 
               batch_size=batch_size,
               epochs=1)  # We only train for one epoch because it's slower.
Train on 60000 samples, validate on 10000 samples
60000/60000 [==============================] - 21s 349us/sample - loss: 0.1457 - accuracy: 0.9567 - val_loss: 0.1881 - val_accuracy: 0.9387

<tensorflow.python.keras.callbacks.History at 0x7f6a5d4f0b00>

見て取れるように、CuDNN で構築されたモデルは通常の TensorFlow カーネルを使用するモデルに比較して訓練するために遥かに高速です。

同じ CuDNN-有効モデルはまた CPU-only 環境で推論を実行するためにも使用できます。下の tf.device アノテーションは単にデバイス配置を強制します。モデルは GPU が利用可能でない場合にデフォルトで CPU 上で動作します。

最早貴方がその上で実行しているハードウェアについて心配する必要は単純にありません。Isn’t that pretty cool?

with tf.device('CPU:0'):
  cpu_model = build_model(allow_cudnn_kernel=True)
  cpu_model.set_weights(model.get_weights())
  result = tf.argmax(cpu_model.predict_on_batch(tf.expand_dims(sample, 0)), axis=1)
  print('Predicted result is: %s, target result is: %s' % (result.numpy(), sample_label))
  plt.imshow(sample, cmap=plt.get_cmap('gray'))
Predicted result is: [5], target result is: 5

 

リスト/辞書入力、またはネストされた入力を持つ RNN

ネストされた構造は実装者に単一の時間ステップ内により多くの情報を含めることを可能にします。例えば、ビデオフレームは音声とビデオ入力を同時に持てるでしょう。この場合のデータ shape は次のようなものであり得ます :

[batch, timestep, {“video”: [height, width, channel], “audio”: [frequency]}]

もう一つの例では、手書きデータは (ペンの) 圧力情報に加えて、ペンの現在の位置のための座標 x と y の両者を持てるでしょうそこでデータ表現は次のようなものでしょう :

[batch, timestep, {“location”: [x, y], “pressure”: [force]}]

以下のコードはそのような構造化入力を受け取るカスタム RNN セルをどのように構築するかの例を提供します。

 

ネストされた入力/出力をサポートするカスタムセルを定義する

NestedInput = collections.namedtuple('NestedInput', ['feature1', 'feature2'])
NestedState = collections.namedtuple('NestedState', ['state1', 'state2'])

class NestedCell(tf.keras.layers.Layer):

  def __init__(self, unit_1, unit_2, unit_3, **kwargs):
    self.unit_1 = unit_1
    self.unit_2 = unit_2
    self.unit_3 = unit_3
    self.state_size = NestedState(state1=unit_1, 
                                  state2=tf.TensorShape([unit_2, unit_3]))
    self.output_size = (unit_1, tf.TensorShape([unit_2, unit_3]))
    super(NestedCell, self).__init__(**kwargs)

  def build(self, input_shapes):
    # expect input_shape to contain 2 items, [(batch, i1), (batch, i2, i3)]
    input_1 = input_shapes.feature1[1]
    input_2, input_3 = input_shapes.feature2[1:]

    self.kernel_1 = self.add_weight(
        shape=(input_1, self.unit_1), initializer='uniform', name='kernel_1')
    self.kernel_2_3 = self.add_weight(
        shape=(input_2, input_3, self.unit_2, self.unit_3),
        initializer='uniform',
        name='kernel_2_3')

  def call(self, inputs, states):
    # inputs should be in [(batch, input_1), (batch, input_2, input_3)]
    # state should be in shape [(batch, unit_1), (batch, unit_2, unit_3)]
    input_1, input_2 = tf.nest.flatten(inputs)
    s1, s2 = states

    output_1 = tf.matmul(input_1, self.kernel_1)
    output_2_3 = tf.einsum('bij,ijkl->bkl', input_2, self.kernel_2_3)
    state_1 = s1 + output_1
    state_2_3 = s2 + output_2_3

    output = [output_1, output_2_3]
    new_states = NestedState(state1=state_1, state2=state_2_3)

    return output, new_states

 

ネストされた入力/出力を持つ RNN モデルを構築する

tf.keras.layers.RNN 層と丁度定義したカスタムセルを使用する Keras モデルを構築しましょう。

unit_1 = 10
unit_2 = 20
unit_3 = 30

input_1 = 32
input_2 = 64
input_3 = 32
batch_size = 64
num_batch = 100
timestep = 50

cell = NestedCell(unit_1, unit_2, unit_3)
rnn = tf.keras.layers.RNN(cell)

inp_1 = tf.keras.Input((None, input_1))
inp_2 = tf.keras.Input((None, input_2, input_3))

outputs = rnn(NestedInput(feature1=inp_1, feature2=inp_2))

model = tf.keras.models.Model([inp_1, inp_2], outputs)

model.compile(optimizer='adam', loss='mse', metrics=['accuracy'])

 

ランダムに生成されたデータでモデルを訓練する

このモデルのための良い候補データセットがありませんので、実演のためにランダムな Numpy データを使用します。

input_1_data = np.random.random((batch_size * num_batch, timestep, input_1))
input_2_data = np.random.random((batch_size * num_batch, timestep, input_2, input_3))
target_1_data = np.random.random((batch_size * num_batch, unit_1))
target_2_data = np.random.random((batch_size * num_batch, unit_2, unit_3))
input_data = [input_1_data, input_2_data]
target_data = [target_1_data, target_2_data]

model.fit(input_data, target_data, batch_size=batch_size)
Train on 6400 samples
6400/6400 [==============================] - 5s 804us/sample - loss: 0.3786 - rnn_1_loss: 0.1166 - rnn_1_1_loss: 0.2620 - rnn_1_accuracy: 0.0997 - rnn_1_1_accuracy: 0.0333

<tensorflow.python.keras.callbacks.History at 0x7f667c8a4b00>

Keras tf.keras.layers.RNN 層では、貴方はシークエンス内の個々のステップのための数学ロジックを定義することが想定されるだけです、そして tf.keras.layers.RNN 層は貴方のためにシークエンス反復を処理します。それは新しい種類の RNN (e.g. LSTM 変種) を素早くプロトタイピングする非常にパワフルな方法です。

より詳細については、API doc を訪ねてください。

 

以上



AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com