Projekt 6
| Strona: | SEZAM - System Edukacyjnych Zasobów Akademickich i Multimedialnych |
| Kurs: | Integracja Technik Sztucznej Inteligencji |
| Książka: | Projekt 6 |
| Wydrukowane przez użytkownika: | Gość |
| Data: | środa, 14 stycznia 2026, 19:25 |
Opis
Budowa
sensorów programowych przy wykorzystaniu sieci neuronowych
1. Zadanie
Celem
zadania jest realizacja, przy wykorzystania sztucznej sieci neuronowej, programowego
czujnika poziomu w trzecim zbiorniku oraz wykorzystanie go do bieżącej
regulacji.
2. Realizacja
Należy wykonać następujące kroki:
- Przeprowadzić stosowny eksperyment i przygotować zbiory danych uczących i testowych dobranych do identyfikacji modelu poziomu wody w zbiorniku 3.
- Wybrać stosowną technikę modelowania (sztuczna sieć neuronowa, uwzględnić możliwość modelowania zależności dynamicznych) i dobrać parametry modelu.
- Przeprowadzić proces uczenia, dokonać weryfikacji odtwarzania poziomu w zbiorniku 3 – zarówno w trybie STD jak i MRO.
- Wprowadzić do symulatora możliwość bieżącego odtwarzania wielkości modelowanej
L3na podstawie przygotowanego modelu oraz wykorzystania jej w bieżącej regulacji jako pomiar wielkościPV. - Ocenić jakość działania układu regulacji z regulatorem PID oraz wielkością
PVodtwarzaną na podstawie modelu (czujnik programowy), w trybie STD oraz MRO, oraz porównać z podstawowym rozwiązaniem.
3. Założenia
- Biorąc pod uwagę dostępny okres próbkowania oraz dynamikę tego fragmentu procesu zakładamy, że szukamy modelu o strukturze \( L_3(k)=f(L_2(k-1),L_3(k-1)) \), gdzie \( k \) oznacza kolejne chwile czasu.
- Porównanie działania układu regulacji z programowym czujnikiem wielkości regulowanej wykonać względem układu regulacji PID z nastawami dobranymi w ramach projektu 1.
- Ocenę jakości działania układu regulacji wykonać dla zmian wokół punktu pracy: \( \delta SP=\pm 0.05 [m] \).
- Do oceny wykorzystywać te same wskaźniki jakości co w projekcie 1.
4. Uwagi
- Predykcja wartości sygnału modelowanego
L3musi działać w pętli sprzężenia zwrotnego, w każdym kroku symulacji musi być wyznaczona nowa wartość poziomu. - W tym przypadku, dodanie nowej struktury przetwarzania, takiej jak model sztucznej sieci neuronowej, najwygodniej zrealizować poprzez dodanie nowego bloku funkcyjnego.
-
W przypadku modelowana wielkości dynamicznych, gdy na wejście modelu podawane są przeszłe wartości sygnału wyjściowego, model taki może być wykorzystywany w dwóch trybach:
- w trybie STD na wejście podawane są przeszłe rzeczywiste wartości sygnału pomiarowego,
- w trybie MRO (Model Reference Output) na wejście podawane są przeszłe (z poprzednich iteracji) wartości wyjścia modelu.
5. Przykłady
W przykładzie wykorzystano sieć neuronową typu Sequencial z biblioteki Keras, o strukturze podobnej jak w projekcie 4.
Do wygenerowania danych uczących wykorzystano generator SP – skoki sygnału SP w całym zakresie zmian. Testy przeprowadzono dla skoków wokół punktu pracy. Dane przygotowano w ten sposób, że dodano do nich dodatkowe kolumny dla sygnałów wejść i wyjścia z modelu opóźnionych o 1 krok (k-1):
dataset_train['L2_1'] = dataset_train['L2'].shift(1)
dataset_train.loc[0, "L2_1"] = dataset_train['L2_1'][1]
dataset_train['L3_1'] = dataset_train['L3'].shift(1)
dataset_train.loc[0, "L3_1"] = dataset_train['L3_1'][1]
dataset_test['L2_1'] = dataset_test['L2'].shift(1)
dataset_test.loc[0, "L2_1"] = dataset_test['L2_1'][1]
dataset_test['L3_1'] = dataset_test['L3'].shift(1)
dataset_test.loc[0, "L3_1"] = dataset_test['L3_1'][1]


Do modelowania wybrano sieć typu Sequential z biblioteki Keras. Wybrano bardzo prostą strukturę sieci, z jedną warstwą ukrytą i funkcjami aktywacji w postaci tanh oraz optymalizatorem Adam. Wykorzystano normalizację sygnałów wejściowych.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# Narmalizacja
normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(np.array(train_features))
# Warstwa wejść i konstrukcja modelu
input_layer = keras.layers.Input(train_features.shape[1:])
model = keras.Sequential([
input_layer,
layers.Dense(2, activation='tanh'),
layers.Dense(1)
])
# Kompilacja modelu
model.compile(loss='mean_absolute_error',
optimizer=tf.keras.optimizers.Adam(0.02))
Na rysunkach poniżej przedstawiono podsumowanie jakości modelowania, zarówno w trybie STD jak i MRO. Jest ona zadawalająca, chociaż widać, że w trybie MRO dokładność modelu spada.
L3 na podstawie modelu neuronowego w trybie STD
L3 na podstawie modelu neuronowego w trybie MROAby osadzić model neuronowy w symulatorze przygotowano dedykowany blok funkcyjny KerasModelFirstOrder (modelling.py), przygotowany do przetwarzania opóźnionych o 1 krok sygnałów we/wy.
from tensorflow import keras
from common.block import Block
from numpy import array
class KerasModelFirstOrder(Block):
def __init__(self, _name, _model, _mode):
super().__init__(_name)
self.add_output(None, 1, 0.018)
self.mode = _mode
self.model = keras.models.load_model('../output/'+_model+'.keras')
def add_input(self, _input, _del=1):
super().add_input(_input, _del)
def calculate(self):
match self.mode:
case 'std':
features = array([[self.input_val_del(0, 1), self.input_val_del(1, 1)]])
case 'mro':
features = array([[self.input_val_del(0, 1), self.output_val_del(0, 1)]])
case _:
features = 0
self.output_val(0, self.model.predict(features, verbose=None)[0][0])
W ostatnim kroku dodano „czujnik programowy” do konfiguracji głównej symulatora (konstruktor klasy TtsPidSim). Dodano także dodatkowy parametr konstruktora _use_L3_modelling, według którego model wykorzystywany jest tylko do odtwarzania wielkości L3 (monit) lub jest także wykorzystywany w pętli sprzężenia zwrotnego jako wielkość regulowana (control):
# Process-Controller feadback: use L3 measurement
if _use_L3_modelling!='control':
pv_measure.add_input(three_tanks.output(2))
# Soft-sensor: modelling L3
if _use_L3_modelling=='monit' or _use_L3_modelling=='control' :
l3_pred = monit_sim.add_block( KerasModelFirstOrder('l3_pred', 'L3_L2_1_L3_1', 'std'))
l3_pred.add_input(l2_dist.output(0))
l3_pred.add_input(l3_dist.output(0))
# Process-Controller feadback: use L3 model output
if _use_L3_modelling=='control':
pv_measure.add_input(l3_pred.output(0))
Pojawiła się także nowa zmienna wyjściowa symulatora L3_pred:
if _use_L3_modelling=='monit' or _use_L3_modelling=='control' :
self.add_out_var('L3_pred', l3_pred.output(0))
Jak widać na rysunkach poniżej osiągnięto zadowalającą, ale daleką od optymalnej, jakość regulacji, zarówno w trybie STD jak i MRO.