TinyML. Compresser le réseau neuronal

Maintenant, les programmeurs sont confrontés à une tâche difficile - comment implémenter une structure aussi lourde qu'un réseau de neurones - dans, par exemple, un bracelet? Comment optimiser la consommation électrique du modèle? Quel est le prix d'une telle optimisation, ainsi que la justification de l'introduction de modèles dans de petits appareils et pourquoi il est impossible de s'en passer.





Et à quoi ça sert?

Imaginons un capteur industriel coûteux - 1000 mesures par seconde, un capteur de température, une mesure des vibrations, une transmission de données sur 10 km, un processeur puissant - 20 millions d'opérations par seconde! Son travail est d'envoyer des données sur la température, les vibrations, ainsi que les valeurs d'autres paramètres au serveur pour éviter les pannes d'équipement. Mais voici la malchance - 99% des données envoyées par lui sont inutiles, de là - une perte nette pour l'électricité. Et il peut y avoir des dizaines et des centaines de capteurs de ce type en production. 





, -   ? ? , ?     , " " " !"  TinyML.





Voyez-vous un sommet très étrange au milieu?  Même une personne qui regarde les lectures des instruments a du mal à le remarquer, mais le modèle ML le fera facilement et "ne manque pas" le moment
? , , " "

, , . "" : , , , , ..





Contrairement au cloud, l'IA intégrée s'exécute sur l'appareil lui-même
, embedded ("") AI

- - . , , WiFi, Bluetooth .





- - . - , " ".





- - . , . , , ... . , ( - TinyML).





- - . - , , .





- - , int , float - .





Quantization

, . - , . , 32 . , 8 ? , .





- 1 . . , .





? . .





La multiplication de la matrice dans ce cas semble "un peu" différente
""

, , . , .





#     
x_values = np.random.uniform(
    low=0, high=2*math.pi, size=1000).astype(np.float32)

# 
np.random.shuffle(x_values)

y_values = np.sin(x_values).astype(np.float32)

#  ,   "   "
y_values += 0.1 * np.random.randn(*y_values.shape)

plt.plot(x_values, y_values, 'b.')
plt.show()
      
      



. , ( , ).





!





#   
model = tf.keras.Sequential()

model.add(keras.layers.Dense(16, activation='relu', input_shape=(1,)))

model.add(keras.layers.Dense(16, activation='relu'))

model.add(keras.layers.Dense(1))

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

#  
history = model.fit(x_train, y_train, epochs=500, batch_size=64,
                    validation_data=(x_validate, y_validate))

# 
model.save(MODEL_TF)
      
      



, :





La qualité qui en résulte convient à nos expériences.

, . "" . TFLiteConverter, .





#      TensorFlow Lite   
converter = tf.lite.TFLiteConverter.from_saved_model(MODEL_TF)
model_no_quant_tflite = converter.convert()

# 
open(MODEL_NO_QUANT_TFLITE, "wb").write(model_no_quant_tflite)

#      TensorFlow Lite  
def representative_dataset():
  for i in range(500):
    yield([x_train[i].reshape(1, 1)])

converter.optimizations = [tf.lite.Optimize.DEFAULT]

#  ,         int
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8

#    ,    
converter.representative_dataset = representative_dataset
model_tflite = converter.convert()

open(MODEL_TFLITE, "wb").write(model_tflite)
      
      



: , TensorFlow Lite , TensorFlow Lite . , .





pd.DataFrame.from_records(
    [["TensorFlow", f"{size_tf} bytes", ""],
     ["TensorFlow Lite", f"{size_no_quant_tflite} bytes ", f"(reduced by {size_tf - size_no_quant_tflite} bytes)"],
     ["TensorFlow Lite Quantized", f"{size_tflite} bytes", f"(reduced by {size_no_quant_tflite - size_tflite} bytes)"]],
     columns = ["Model", "Size", ""], index="Model")
      
      



, , TensorFlow Lite 32% , 40% ! , , ?





, . , , !





Python , , , ? , . ! Ubuntu, Windows - .





#  xxd
!apt-get update && apt-get -qq install xxd
#   
!xxd -i {MODEL_TFLITE} > {MODEL_TFLITE_MICRO}
#   
REPLACE_TEXT = MODEL_TFLITE.replace('/', '_').replace('.', '_')
!sed -i 's/'{REPLACE_TEXT}'/g_model/g' {MODEL_TFLITE_MICRO}
#  ,       C  
!cat {MODEL_TFLITE_MICRO}
      
      



, 400.





, , , , . ( ) . , , - .






//   ,     

  float x = 0.0f;
  float y_true = sin(x);

  // 
  tflite::MicroErrorReporter micro_error_reporter;

  //    
  const tflite::Model* model = ::tflite::GetModel(g_model);
      
      



. ? , : , . - , . , .





, :





  x = 5.f;
  y_true = sin(x);
  input->data.int8[0] = x / input_scale + input_zero_point;
  interpreter.Invoke();
  y_pred = (output->data.int8[0] - output_zero_point) * output_scale;
  TF_LITE_MICRO_EXPECT_NEAR(y_true, y_pred, epsilon);
      
      



Edge Impulse

Edge Impulse , TinyML.





, , . , , , - .





- TinyML . ( , ..) . 20% , , .





, NoML Community - https://t.me/noml_community.








All Articles