Телефонуйте » (+38) 096 227 41 41

tf.keras є реалізацією специфікації Keras API для TensorFlow. Цей високорівневий API ефективний для побудови та навчання моделей. tf.keras робить використання TensorFlow простішим, не жертвуючи при цьому гнучкістю і продуктивністю.

Імпорт tf.keras

Для початку, імпортуємо tf.keras, як частину встановлення нашого TensorFlow:

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow import keras

tf.keras може виконати будь-який Keras-сумісний код, але треба прийняти до уваги:

⦁    Версія tf.keras в останньому релізі TensorFlow може відрізнятися від останньої версії keras в PyPI. Перевірте версію з tf.keras.__version__.
⦁    При збереженні вагових коефіцієнтів моделей, tf.keras робить це за замовчуванням у форматі checkpoint (TensorFlow). Для використання HDF5 треба передати параметр save_format='h5' (або додати до назви файла розширення .h5).

Будуємо просту модель

Послідовна модель

В Keras, ми збираємо шари (layers) для побудови моделей (models). Модель - це (зазвичай) граф шарів. Найбільш розповсюдженим видом моделі є стек шарів: модель tf.keras.Sequential.
Побудуємо просту повністю зв’язану мережу (тобто, багатошаровий перцептрон) (рис. 1):

Послідовна модель мережі з двома схованими шарами
Рис. 1 Послідовна модель мережі з двома схованими шарами

Код:

from tensorflow.keras import layers
model = tf.keras.Sequential()
# Додамо до моделі повністю зв’язаний шар з 64 вузлами:
model.add(layers.Dense(64, activation='relu'))
# Додамо другий шар:
model.add(layers.Dense(64, activation='relu'))
# Додамо шар з функцією активації softmax з 10 виходами:
model.add(layers.Dense(10, activation='softmax'))

Налаштовуємо шари

Доступні багато різновидів шарів tf.keras.layers. Більшість з них використовують спільний конструктор аргументів:

⦁    activation: Установка функції активації для шара. В цьому параметрі вказується назва вбудованої функції або об’єкт, який викликається. Параметр не має значення за замовчуванням.
⦁    kernel_initializer і bias_initializer: Схеми ініціалізації створюють вагові коефіцієнти шару (ядро і зсув). В цьому параметрі може бути назва або об’єкт, який викликається. За замовчуванням використовується ініціалізатор "Glorot uniform".
⦁    kernel_regularizer і bias_regularizer: Схеми регуляризації, які додаються до вагових коефіцієнтів шару (ядро і зсув), такі як L1 або L2 регуляризації. За замовчуванням регуляризація не встановлюється.

Наступні приклади примірників шарів `tf.keras.layers.Dense` використовують аргументи конструктора:

# Створимо шар з функцією активації сигмоїда:
layers.Dense(64, activation='sigmoid')
# Або:
layers.Dense(64, activation=tf.keras.activations.sigmoid)

# Лінійний шар з регуляризацією L1 з коефіцієнтом 0.01, застосованої до матриці ядра:
layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))

# Лінійний шар з регуляризацією L2 з коефіцієнтом 0.01, застосованої до вектора зсуву:
layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))

# Лінійний шар з ядром, ініціалізованим випадковою ортогональною матрицей:
layers.Dense(64, kernel_initializer='orthogonal')

# Лінійний шар з вектором зсуву, ініціалізованим значеннями 2.0:
layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))


Навчаємо та оцінюємо

Налаштування навчання

Після того, як модель зконструйована, налаштуємо процес її навчання викликом метода compile:

model = tf.keras.Sequential([
# Додаємо до моделі повністю зв’язаний шар з 64 вузлами:
layers.Dense(64, activation='relu', input_shape=(32,)),
# Додаємо другий шар:
layers.Dense(64, activation='relu'),
# Додаємо шар з функцією активації softmax з 10 виходами:
layers.Dense(10, activation='softmax')])

model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
              loss='categorical_crossentropy',
              metrics=['accuracy'])


tf.keras.Model.compile приймає три важливих аргумента:

⦁    optimizer: Цей об’єкт визначає процедуру навчання. Передаємо в нього примірники оптимізатора з модуля tf.keras.optimizers, такі як tf.keras.optimizers.Adam або tf.keras.optimizers.SGD. Якщо ми просто хочемо використати параметри за замовчуванням, то можемо також вказати оптимізатори такими ключовими словами, як 'adam' або 'sgd'.
⦁    loss: Це функція, яка мінімізується в процесі навчання. Серед розповсюджених варіантів середньоквадратична помилка (mse), categorical_crossentropy, binary_crossentropy. Функції втрат вказуються за назвою або передачею об’єкта, який викликається, з модуля tf.keras.losses.
⦁    metrics: Використовується для моніторингу навчання. Це рядкові імена або об’єкти, які викликаються з модуля tf.keras.metrics.
⦁    Крім того, щоб бути впевненим, що модель навчається та оцінюється eagerly, перевіряємо, що передали компілятору параметр run_eagerly=True

Далі подивимось кілька прикладів конфігурації моделі для навчання:

# Конфігуруємо модель для регресії з середньоквадратичною помилкою.
model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
              loss='mse',       # середньоквадратична помилка
              metrics=['mae'])  # середня абсолютна помилка

# Конфігуруємо модель для категорійної класифікації.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.01),
              loss=tf.keras.losses.CategoricalCrossentropy(),
              metrics=[tf.keras.metrics.CategoricalAccuracy()])


Навчання з даними NumPy

Для невеликих наборів даних використовуємо для навчання і оцінювання моделі масиви NumPy, які розміщуються в пам’яті. Модель «навчається» на тренувальних даних, використовуючи метод `fit`:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.fit(data, labels, epochs=10, batch_size=32)

Навчання моделі
Рис.2. Навчання моделі

tf.keras.Model.fit приймає три важливих аргумента:

⦁    epochs: Навчання розбито на *епохи*. Епоха - одна ітерація по всім вхідних даних (це робиться невеликими партіями).
⦁    batch_size: При передачі даних NumPy, модель розбиває дані на менші блоки (batches) та виконує ітерації по цих блоках під час навчання. Це число вказує розмір кожного блока даних. Пам’ятайте, що останній блок може бути меншого розміру, якщо загальне число записів не ділиться на розмір партії.
⦁    validation_data: При прототипуванні моделі ми хочемо легко відстежувати її продуктивність на валідаційних даних. Передача з цим аргументом кортежа вхідних даних і міток дозволяє моделі відображати значення функції втрат і метрики в режимі виводу для даних, які передаються в кінці кожної епохи.

Нижче приклад використання validation_data:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

val_data = np.random.random((100, 32))
val_labels = np.random.random((100, 10))

model.fit(data, labels, epochs=10, batch_size=32,
          validation_data=(val_data, val_labels))

Валідація даних
Рис.3. Валідація даних

Навчання з використанням наборів даних tf.data

Використовуємо Datasets API для маштабування великих баз даних або навчання на декількох пристроях. Передаємо примірник `tf.data.Dataset` в метод fit:

# Створює примірник навчального набору даних:
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.fit(dataset, epochs=10)

Тренування з tf.data
Рис. 4. Тренування з tf.data

Оскільки Dataset видає дані пакетами, то цей шматок коду не вимагає аргумента batch_size.
Набори даних також можуть бути використані для валідації:

dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
val_dataset = val_dataset.batch(32)

model.fit(dataset, epochs=10,
          validation_data=val_dataset)

Валідація з tf.data
Рис. 5. Валідація з tf.data

Оцінювання і передбачення

Методи tf.keras.Model.evaluate і tf.keras.Model.predict можуть використовувати дані NumPy і tf.data.Dataset.

Можна оцінити втрати в режимі виводу і метрики для наданих даних таким чином:

# З масивом Numpy
data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.evaluate(data, labels, batch_size=32)

# З набором даних (датасетом)
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.evaluate(dataset)

Результат виконання:

1000/1 [======] - 0s 53us/sample - loss: 249148.8575 - categorical_accuracy: 0.0960
32/32 [=======] - 0s 2ms/step - loss: 262983.5693 - categorical_accuracy: 0.0960

[262983.5693359375, 0.096]


Виведення передбачення як висновку з останнього шару для даних, наданих у вигляді масиву NumPy:

result = model.predict(data, batch_size=32)
print(result.shape)

Результат виконання:

(1000, 10)

Детальніше про тренування та оцінювання, включаючи, як писати спеціальні цикли тренування з нуля, дивіться у посібнику з навчання та оцінювання.

Побудова складних моделей

Functional API

Модель tf.keras.Sequential – це простий стек шарів за допомогою якого не можна представити довільну модель. Для побудови складних топологій моделей будемо використовувати Keras functional API. Серед цих моделей:

⦁    Моделі з кількома входами.
⦁    Моделі з кількома виходами.
⦁    Моделі із загальними шарами (один і той же шар викликається кілька разів).
⦁    Моделі з непослідовними потоками даних (наприклад, залишкові зв’язки).

Побудова моделі з використанням functional API виконується таким чином:

1.    Можна викликати примірник шару і при цьому буде повернутий тензор.
2.    Для визначення примірника tf.keras.Model використовуються вхідні та вихідні тензори.
3.    Дана модель навчається точно так же, як і модель `Sequential`.

Наступний приклад використовує functional API для побудови простої, повністю зв’язаної мережі:

inputs = tf.keras.Input(shape=(32,))  # Повертає вхідний плейсхолдер

# Примірник шару викликається на тензор і повертає тензор.
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dense(64, activation='relu')(x)
predictions = layers.Dense(10, activation='softmax')(x)


Примірник моделі, заданий входами і виходами.

model = tf.keras.Model(inputs=inputs, outputs=predictions)

# Крок компіляції визначає конфігурацію навчання.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Навчання за 5 епох
model.fit(data, labels, batch_size=32, epochs=5)


Підкласи моделей

Створимо повністю налаштовувану модель за допомогою підкласу tf.keras.Model і визначення нашого власного прямого розповсюдження. Створюємо шари в методі __init__ і встановлюємо їх як атрибути примірника класу. Визначаємо пряме розповсюдження в методі call.

Підклас моделі особливо корисний, коли включений eager execution, оскільки він дозволяє написати пряме розповсюдження імперативно (в обов’язковому порядку).

Примітка: Якщо нам треба, щоб наша модель завжди виконувалась імперативно, то можемо встановити dynamic=True, коли викликаємо конструктор super.

Ключовий момент: Використовуйте правильний API для роботи. Хоча підкласи моделі забезпечують гнучкість, за неї доводиться платити більшою складністю і великими можливостями для помилок користувача. Якщо можливо, то вибирайте functional API.

Наступний приклад показує підкласову модель tf.keras.Model, яка використовує пряме розповсюдження користувача, яке не обов’язково виконувати імперативно:
class MyModel(tf.keras.Model):

  def __init__(self, num_classes=10):
    super(MyModel, self).__init__(name='my_model')
    self.num_classes = num_classes
    # Тут визначаємо свої шари.
    self.dense_1 = layers.Dense(32, activation='relu')
    self.dense_2 = layers.Dense(num_classes, activation='sigmoid')

  def call(self, inputs):
    # Тут визначаємо своє пряме розповсюдження,
    # з використанням раніше визначених шарів (в `__init__`).

    x = self.dense_1(inputs)
    return self.dense_2(x)


Створюємо примірник класу нової моделі:

model = MyModel(num_classes=10)

# Крок компіляції визначає конфігурацію навчання.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Навчання за 5 епох.
model.fit(data, labels, batch_size=32, epochs=5)


Шари користувача

Створюємо шар користувача підкласом tf.keras.layers.Layer і реалізацією наступних методів:

⦁    __init__: Опціонально визначаємо підшари, які будуть використовуватися в цьому шарі.
⦁    * build: Створюємо вагові коефіцієнти шара. Додаємо їх за допомогою методу add_weight
⦁    call: Визначаємо пряме розповсюдження.
⦁    Опціонально, шар може бути серіалізований за допомогою метода get_config і метода класу from_config.

Нижче приклад шара користувача, який здійснює множення матриці (matmul), поданої на вхід, на матрицю ядра:

class MyLayer(layers.Layer):

  def __init__(self, output_dim, **kwargs):
    self.output_dim = output_dim
    super(MyLayer, self).__init__(**kwargs)

  def build(self, input_shape):
    # Створюємо вагову змінну для навчання цього шару.
    self.kernel = self.add_weight(name='kernel',
                                  shape=(input_shape[1], self.output_dim),
                                  initializer='uniform',
                                  trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.kernel)

  def get_config(self):
    base_config = super(MyLayer, self).get_config()
    base_config['output_dim'] = self.output_dim
    return base_config

  @classmethod
  def from_config(cls, config):
    return cls(**config)


Створюємо модель з використанням нашого шару користувача:

model = tf.keras.Sequential([
    MyLayer(10),
    layers.Activation('softmax')])
# Крок компіляції визначає конфігурацію навчання
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Навчання за 5 епох.
model.fit(data, labels, batch_size=32, epochs=5)

Більше дізнатися про створення нових шарів і моделей за допомогою scratch з підмоделями можна в Посібнику з запису шарів та моделей наscratch.

Сallbacks – зворотні виклики

Зворотний виклик - це об'єкт, переданий моделі для налаштування та розширення її поведінки під час тренінгу. Ми можемо написати свій зворотний виклик користувача або використати вбудований tf.keras.callbacks, який включає:

⦁    tf.keras.callbacks.ModelCheckpoint: Збереження контрольних точок моделі через регулярні інтервали.
⦁    tf.keras.callbacks.LearningRateScheduler: Динамічна зміна кроку навчання.
⦁    tf.keras.callbacks.EarlyStopping: Зупинка навчання в тому випадку, коли результат при валідації перестає покращуватися.
⦁    tf.keras.callbacks.TensorBoard: Моніторинг поведінки моделі за допомогою TensorBoard

Для використання tf.keras.callbacks.Callback передаємо її методу моделі fit:

callbacks = [
  # Зупинення навчання, якщо `val_loss` перестане покращуватися протягом 2 епох
  tf.keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
  # Записування логів TensorBoard в каталог `./logs` directory
  tf.keras.callbacks.TensorBoard(log_dir='./logs')
]
model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
          validation_data=(val_data, val_labels))


tf.keras підтримує класи Metric, які можуть оцінювати показники на кожній партії. Однак у нього є обмеження, бо він може обчислювати лише дані тренувань і виводити лише одне значення.
Це стає проблемою, особливо в тих випадках, коли користувач робить оцінку валідації і йому потрібно записувати більше, ніж одну метрику одночасно. Callback більше підходить для оцінки набору періодичної валідації, оскільки виконувати це буде на повільному та обчислювальному рівні на кожному етапі навчання. Однак, власний callback не вирішує проблему збереження будь-яких обчислених значень у tf.summary, щоб користувач міг відстежувати ці значення з TensorBoard. Але цю частину можна «зламати».

По-перше, потрібно повернути ванільний зворотний виклик TensorBoard та передати його на наш власний зворотний виклик:

import tensorflow as tf
from .test_callback import TestCallback


model = tf.keras.Model()

tb_callback = tf.keras.callbacks.TensorBoard("somedir")
test_callback = TestCallback(tb_callback)

callbacks = [
    tb_callback,
    test_callback
]

model.fit(x_data, y_data, batch_size=8, epochs=10, callbacks=callbacks)

TestCallback виглядає так:

import tensorflow as tf

class TestCallback(tf.keras.callbacks.Callback):


    def __init__(self, tb_callback):

        self.tb_callback = tb_callback
        self.step_number =0


    def on_epoch_end(self, epoch, logs=None):

        test_input = "something"
        test_gt = "some ground truth data"

        test_output = self.model.predict(test_input)

        metric1, metric2 = get_metrics(test_gt, test_output)

        items_to_write={
            "metric1_name": metric1,
            "metric2_name": metric2
        }

        writer = self.tb_callback.writer

        for name, value in items_to_write.items():

            summary = tf.summary.Summary()
            summary_value = summary.value.add()
            summary_value.simple_value = value
            summary_value.tag = name
            writer.add_summary(summary, self.step_number)
            writer.flush()

        self.step_number += 1

Тепер за допомогою TensorBoard зможемо відстежувати процес навчання.

Збереження і відновлення

Збереження значень лише вагових коефіцієнтів

Збережемо і завантажимо вагові коефіцієнти моделі за допомогою tf.keras.Model.save_weights:

model = tf.keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(32,)),
layers.Dense(10, activation='softmax')])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Збережемо вагові коефіцієнти в файл TensorFlow Checkpoint
model.save_weights('./weights/my_model')

# Відновимо стан моделі.
# Для цього необхідна модель з такою ж архітектурою.

model.load_weights('./weights/my_model')


За замовчуванням вагові коефіцієнти моделі зберігаються у форматі TensorFlow checkpoint. Вони можуть бути також збережені у форматі HDF5 Keras (значення за замовчуванням для універсальної реалізації Keras):

# Збереження вагових коефіцієнтів у файлі HDF5
model.save_weights('my_model.h5', save_format='h5')

# Відновлення стану моделі
model.load_weights('my_model.h5')


Збереження лише конфігурації моделі

Конфігурація моделі може бути збережена - це серіалізує архітектуру моделі без будь-яких вагових коефіцієнтів. Збережену конфігурацію можна відновити та ініціалізувати ту ж модель, навіть без коду, який визначає первинну модель. Keras підтримує формати серіалізації JSON і YAML:

# Серіалізація моделі в формат JSON
json_string = model.to_json()
json_string

import json
import pprint
pprint.pprint(json.loads(json_string))


Відновлення моделі (заново ініціалізованої) з JSON:

fresh_model = tf.keras.models.model_from_json(json_string)

Серіалізація моделі в формат YAML вимагає встановлення `pyyaml` перед тим, як імпортувати TensorFlow:

yaml_string = model.to_yaml()
print(yaml_string)


Відновлення моделі з YAML:

fresh_model = tf.keras.models.model_from_yaml(yaml_string)

Увага: підкласові моделі не можуть серіалізуватися, тому що їх архітектура визначається кодом Python в тілі метода `call`.

Збереження всієї моделі в один файл

Вся модель може бути збережена у файл, в який входять значення вагових коефіцієнтів, конфігурація моделі і навіть конфігурація оптимізатора. Це дозволить нам встановити контрольну точку моделі і продолжити навчання пізніше з точно того ж положення навіть без доступу до первинного коду.

# Створимо просту модель
model = tf.keras.Sequential([
  layers.Dense(10, activation='softmax', input_shape=(32,)),
  layers.Dense(10, activation='softmax')
])
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(data, labels, batch_size=32, epochs=5)

# Збережемо всю модель в файл HDF5
model.save('my_model.h5')

# Перестворимо точно цю ж модель, в тому числі вагові коефіцієнти і оптимізатор.
model = tf.keras.models.load_model('my_model.h5')

Результат виконання:

Train on 1000 samples
Epoch 1/5
1000/1000 [=================] - 0s 404us/sample - loss: 11.4749 - accuracy: 0.1130
Epoch 2/5
1000/1000 [=================] - 0s 73us/sample - loss: 11.4722 - accuracy: 0.1040
Epoch 3/5
1000/1000 [=================] - 0s 75us/sample - loss: 11.4959 - accuracy: 0.1060
Epoch 4/5
1000/1000 [=================] - 0s 73us/sample - loss: 11.5455 - accuracy: 0.0990
Epoch 5/5
1000/1000 [=================] - 0s 74us/sample - loss: 11.5848 - accuracy: 0.0970

Eager execution

Eager execution - це імперативне середовище програмування, яке виконує операції негайно. Цього не вимагається для Keras, але підтримується tf.keras і корисно для перевірки нашої програми і налагодження.

Всі побудовані моделі API `tf.keras` сумісні eager execution. І хоча можна використати `Sequential` і functional API, eager execution особливо корисна при моделі з підклассами і побудові шарів користувача - ці API вимагають від нас написання прямого розповсюдження у вигляді коду (замість API, які створюють моделі шляхом збірки існуючих шарів).

Розподілення

Множинні GPU

tf.keras моделі можно запускати на множині GPU з використанням tf.distribute.Strategy. Цей API забезпечує розподілене навчання на кількох GPU практично без змін в існуючому коді.

На сьогодні, tf.distribute.MirroredStrategy є єдиною підтримуваною стратегією розподілення. MirroredStrategy виконує реплікацію в графах з синхронним навчанням, використовуючи all-reduce на одній машині. Для використання `distribute.Strategy`, треба вкласти інсталяцію оптимізатора, конструкцію і компіляцію моделі в `Strategy` `.scope()`, потім навчимо модель.

Наступний приклад розподіляє tf.keras.Model між множиною GPU на одній машині.
Спочатку визначимо модель всередині області розподіленої стратегії:

strategy = tf.distribute.MirroredStrategy()

with strategy.scope():
  model = tf.keras.Sequential()
  model.add(layers.Dense(16, activation='relu', input_shape=(10,)))
  model.add(layers.Dense(1, activation='sigmoid'))

  optimizer = tf.keras.optimizers.SGD(0.2)

  model.compile(loss='binary_crossentropy', optimizer=optimizer)

model.summary()

Результат виконання:

Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_21 (Dense)             (None, 16)                176       
_________________________________________________________________
dense_22 (Dense)             (None, 1)                 17        
=================================================================
Total params: 193
Trainable params: 193
Non-trainable params: 0
_________________________________________________________________

Потім навчимо модель на даних, як зазвичай:

x = np.random.random((1024, 10))
y = np.random.randint(2, size=(1024, 1))
x = tf.cast(x, tf.float32)
dataset = tf.data.Dataset.from_tensor_slices((x, y))
dataset = dataset.shuffle(buffer_size=1024).batch(32)

model.fit(dataset, epochs=1)

Результат виконання:

32/32 [==============================] - 2s 75ms/step - loss: 0.7055

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

Для більшої інформації, перегляньте повне керівництво з Distributed Training in TensorFlow.

Література

1. https://www.tensorflow.org/guide/keras/overview
2. https://chadrick-kwag.net/how-to-manually-write-to-tensorboard-from-tf-keras-callback-useful-trick-when-writing-a-handful-of-validation-metrics-at-once/

Попереднє заняття - Наступне заняття

Новини

  • SDR в IoT

    iotSDR пропонує платформу розробок для IoT-радіо та мережевих доменів. На платі два передавачі Microchip AT86RF215, для вводу-виводу модему на Xilinx ZYNQ SoC, приймач GNSS MAX2769 для GPS, Galileo, BieDou та Glonass. Плата сумісна з ПЗ GNURadio SDR. Дозволяє розробити протоколи фізичного рівня LoRa, SigFox, WightLess, Bluetooth, BLE, 802.15.4, ZigBee тощо для IoT, або шлюз IoT через TheThingsNetwork, LPWAN або Google Thread. Пам'ять EEPROM: 1x AT24MAC602 , flash-пам'ять: 1x QSPI 128 Мб, RAM: 256 MБ DDR3,слот для Micro SD карти, входи/виходи: 2x 8-бітних інтерфейси PL, інтерфейс 8-бітного PS, Gigabit Ethernet, USB 2.0 (USB3310), USB 2.0 (CP2104), 2x SMA RF-роз'єми для приймача діапазонів IoT, 2x SMA RF-роз'єми для приймача 2,4 ГГц , RF-роз'єм приймач GNSS, FPGA-роз'єм JTAG для програмування. Розміри плати: 76,2 мм x 101,6 мм.

     

    in Новини

Записатися на курс