數字孿生實戰【Python源碼】

本文將介紹如何使用 Python 構建電子開關(晶體管)的數字孿生。

1、什麼是數字孿生?

IBM 將數字孿生定義如下“數字孿生是一種旨在準確反映物理對象的虛擬模型”,並指出創建數字孿生的主要促成因素是如何收集數據的傳感器和以某種特定格式/模型將數據插入到對象的數字副本中的處理系統。

此外,IBM 表示,“一旦獲知此類數據,虛擬模型可用於運行模擬、研究性能問題併產生可能的改進”。

所以,我們可以畫出這個心智模型:

在這裏插入圖片描述

2、使用 Python 創建數字孿生

那麼,如何使用我們最喜歡的語言 Python 來創建數字孿生呢?爲什麼我們甚至認爲它會起作用?

答案很簡單。只需看上圖,然後再看下圖,就可以看到數字孿生模型和經典 Python 對象之間的等價關係。我們可以使用合適的方法/函數模擬傳感器和數據處理器,將收集到的數據存儲在數據庫或內部變量中,並將所有內容封裝到 Python 類中。

在這裏插入圖片描述

一旦我們完成了這一點,也可以希望 Python 對象

  • 可用於合適的模擬程序,
  • 可以探測數據,並且
  • 甚至可以接受優化程序以增強合適的內部參數。

當然,我們可以爲該方案添加幾乎無限的複雜層,並使對象成爲真正複雜的數字構造。但是,遵循奧卡姆剃刀原則,我們應該從簡單開始,然後逐步增加複雜性。

…創建數字孿生的主要促成因素是收集數據的傳感器和處理系統……

在本文中,我們將採用簡單的分步方法從單個半導體器件(物理對象)中創建數字孿生對象。爲了簡單起見,我們甚至不會對傳感器進行建模,而是將它們模擬爲半導體器件上的簡單端電壓。

3、物理對象 - MOSFET 器件

我們周圍有一些物理對象體現了現代文明的進程。不完整的列表可能如下所示,

  • 內燃機——體現了所有的機動性
  • 印刷機——包含所有知識
  • 電動機——體現所有工業運動
  • 基於半導體的晶體管 - 體現了所有電子/互聯網

在加入數據科學領域之前,我在半導體行業工作了十多年。自然,我會被這個數字孿生演示的相關示例所吸引。

在這裏插入圖片描述

那麼,什麼是MOSFET?

儘管最早的半導體晶體管是所謂的“雙極結器件”,但幾乎所有現代晶體管都是稱爲 MOSFET 的形式。它是一個縮寫詞,代表“金屬-氧化物-半導體場-效應-晶體管”。

基本上,它是一種由金屬和半導體(例如硅或鍺)層製成的器件,中間夾着一層薄的氧化物(或其他電絕緣體)材料層。

這是最早的MOSFET專利之一的歷史形象,

在這裏插入圖片描述

我們可以通過採用具有三個端子(漏極、源極和柵極)的器件模型(也稱爲電路模型)來簡化內部結構。

在這裏插入圖片描述

4、我們要建模的MOSFET特徵

這是構建數字孿生時的首要考慮因素之一——我們想要在數字對象中建模哪些特徵。這決定了孿生的複雜性和數據結構選擇。

例如,雖然我們可以用 MOSFET 結構來模擬各種複雜的物理現象,但我們可能會選擇將自己限制在只模擬最基本的特性,即。最簡單形式的漏源電流和電壓關係。

在這裏插入圖片描述

現在,我們沒有足夠的時間在本文中詳細解釋所有這些特徵(及其基礎物理)。有興趣的讀者可以參考優秀的網上資料

5、MOSFET是數字開關

記住 MOSFET 行爲的最簡潔方法是將其想象爲數字開關。下面是它的工作原理,

  • 如果Gate和Source之間的電壓低於某個閾值,則開關關閉,並且在Drain和Source之間沒有電流(或信息)流動。這顯示在上圖的右下角。
  • 當柵極到源極電壓高於此閾值時,開關打開。漏源電流也由它們之間的電壓決定。這顯示在上圖的右上角。

因此,MOSFET 的基本用途是作爲電壓控制開關,即我們可以通過控制第三個端子上的電壓來控制其兩個端子之間的電流(或信息)量。

我們想在數字對象中建模哪些特徵?這決定了數字孿生的複雜性和數據結構選擇

考慮到這一點,創建數字孿生唯一要記住的是通用 MOSFET 的三個重要參數,

  • Vth:它是閾值電壓(在Gate和Source之間),高於該閾值,開關就會導通。
  • gm:這是 MOSFET 在導通後可以在漏極和源極之間傳輸電流的“簡易性” 。這個數字越高,電流越大。它可以被認爲是電阻的倒數(表示給定電壓下電流流動的電阻)。
  • BV:這稱爲“擊穿電壓”。這沒有在理想的開關描述中討論,也不會在數字孿生中建模。這代表了 MOSFET 在其處於關斷狀態時可以在其漏極和源極之間保持多少電壓的限制。超過此限制,MOSFET 再次開始導通,但不是以受控方式,即我們無法控制電流,它基本上是無用的。但是,此參數對於設計和建模很重要,因爲它限制了特定應用中特定設備的選擇。

記住,MOSFET 的基本用途是作爲電壓控制開關……

6、Python 數字孿生

此演示的樣板代碼在Github 庫中。爲簡潔起見,我將僅在本文中展示部分代碼片段。

6.1 MOSFET類

我們定義了主要的 MOSFET 類,用戶可以選擇還定義一些參數和端電壓。部分代碼如下所示:

class MOSFET: 
    def __init__(self,params=None,terminals=None): 
        
        # Params
         if params is None: 
            self._params_ = {'BV':20, 
                             'Vth':1.0, 
                             'gm':1e-2} 
        else : 
            self._params_ = params 
        
        # Terminals
         if terminal is None: 
            self._terminals_ = {'source':0.0, 
                        'drain':0.0, 
                        'gate':0.0} 
        else: 
            self._terminals_ = terminal

在這段代碼中,可以觀察到我們之前詳細討論過的熟悉的終端和參數。有一些默認參數。

我們也可以有一種__repr__方法來用一行來描述對象:

def __repr__(self):
        return "Digital Twin of a MOSFET"

6.2 一種確定開關狀態的方法

通過在類中定義一個方法,我們可以輕鬆地將數字開關(ON/OFF)的 MOSFET 特性轉換爲編程邏輯。

def determine_state(self,vgs=None):
        """
        """
        if vgs is None:
            vgs = self._terminals_['gate'] - self._terminals_['source']
        else:
            vgs = vgs
        if vgs > self._params_['Vth']:
            return 'ON'
        else:
            return 'OFF'

在該__init__方法中,我們可以從對象的實例化中確定狀態。

# Determine state
  self._state_ = self.determine_state()

我們已經掌握了定義具有特徵和行爲的數字孿生的竅門,對吧?

6.3 快速示例

在深入探討其他特徵之前,讓我們先看看迄今爲止定義的這個數字孿生的行爲。

mosfet = MOSFET()

在Jupyter notebook中,我們輸入這個來測試一行描述:

mosfet
>> Digital Twin of a MOSFET

我們測試mosfet對象的狀態:

mosfet._state_
>> 'OFF'

我們以這種方式獲取默認參數的字典:

mosfet._params_
>> {'BV': 20, 'Vth': 1.0, 'gm': 0.01}

現在,如果我們顯式定義一個帶有一些終端和參數值的對象:

mosfet = MOSFET(terminals={'source':0.0,
            'drain':0.0,
            'gate':2.0}, 
           params={'BV':20,
                   'Vth':1.0,
                   'gm':1e-2})

你認爲這個對象的狀態是什麼?讓我們看一下:

mosfet._state_
>> 'ON'

MOSFET(或其數字孿生)處於打開狀態,因爲柵極和源極之間的電壓大於實例中定義的參數Vth 。我再次重複代碼片段,突出顯示感興趣的部分:

terminals={'source':0.0,
            'drain':0.0,
            'gate':2.0}

以及:

params={'BV':20,
        'Vth':1.0,
        'gm':1e-2})

6.4 具有分析模型的方法

接下來,我們使用簡單的一階分析模型計算導通狀態 MOSFET 的漏源電流。代碼和方程式都包含在Notebook中,這裏我只展示部分代碼片段:

def id_vd(self,vgs=None,vds=None,rounding=True):
        """
        Calculates drain-source current from 
        terminal voltages and gm
        """
        <code>
        if state=='ON':
            if vds <= vgs - vth:
                ids = self._params_['gm']*(vgs - vth - (vds/2))*vds
            else:
                ids = (self._params_['gm']/2)*(vgs-vth)**2
         
        <more code...>

更有趣的是,檢查數字孿生是否可以產生類似於物理設備的電流-電壓特性。我們可以爲一系列漏源電壓計算一系列漏源電流:

ids = []
mosfet = MOSFET()
vds_vals = [0.01*i for i in range(1,501)]
for v in vds_vals:
    ids.append(mosfet.id_vd(vgs=3.0,vds=v,rounding=False))

結果看起來與通用的理想 MOSFET 特性完美匹配。這裏Vds(x軸)代表漏極-源極電壓,Ids(y軸)代表漏極-源極電流:

在這裏插入圖片描述

分析模型也涉及柵極-源極電壓 (Vgs),因此,我們可以計算一系列 Vgs 的 Ids 與 Vds 曲線。結果看起來像: 在這裏插入圖片描述

7、現代數字孿生—深度學習

數字孿生建模不一定需要來自數據科學或機器學習的工具。然而,在以數據驅動模型爲主的現代世界中,在適用和合適的地方使用此類建模技術是謹慎的。

這並不意味着您應該從數字孿生中消除所有分析模型,並開始在每個特徵上投入深度學習模型。作爲領域專家(或者如果你不是領域專家,則在專家的幫助下),必須確定分析和機器學習模型(甚至離散仿真模型)的平衡組合,以嵌入到數字孿生對象中以表示實物資產的真實世界特徵。

在這裏插入圖片描述

記住:數字孿生建模不一定需要來自數據科學或機器學習的工具。

7.1 使用神經網絡對亞閾值泄漏進行建模

那麼,我們應該在我們的數字孿生對象中應用合適的機器學習技術嗎?事實證明,計算(或使用 ML 估計器預測)所謂的“亞閾值泄漏”將是一個很好的選擇。

這是什麼“亞閾值泄漏”?

如前所述,當 Vgs 低於 Vth 時,MOSFET 處於關斷狀態。因此,它的理想行爲是在漏極和源極之間承載零電流。然而,由於奇妙的量子力學(我們不需要知道細節),一個真正的 MOSFET 即使在關斷狀態下也會攜帶少量的“泄漏”電流。我們可以嘗試使用 ML 模型(特別是深度神經網絡 (DNN))來計算這一點。

7.2 ML 模型——爲什麼以及如何選擇?

那麼,爲什麼我們選擇一個解析方程來模擬導通狀態下的 Ids-Vds 和一個 DNN 來模擬漏電流呢?

這個問題沒有正確或錯誤的答案。這取決於幾個因素,

  • 你擁有的數據的類型和性質
  • 你嘗試建模的物理過程的性質和複雜性
  • 數字孿生模型的性能和準確性之間的權衡

在這種情況下,泄漏電流的測量通常是嘈雜的。實際值也具有一定的隨機性,這是創建物理 MOSFET 的材料特性和製造工藝的自然變化的強大函數。物理學還表明它是端電壓和一些其他內部參數的非線性函數。所有這些都使得 ML 方法適用於對這一特徵進行建模。

對於創建的每個數字孿生,我們都必須深入調查並根據判斷做出選擇。然而,數字孿生的美妙之處在於,它允許你隨時用 ML 模型替換分析模型(反之亦然)。

必須確定分析和機器學習模型(甚至離散仿真模型)的平衡組合,以嵌入到數字孿生對象中

7.3 模型訓練方法

模型訓練和預測接口的選擇是完全靈活的。在這個例子中,我們有單獨的訓練和預測方法。訓練方法的代碼片段如下所示。

def train_leakage(self,data=None,
                      batch_size=5,
                      epochs=20,
                      learning_rate=2e-5,
                      verbose=1):
        """
        Trains the digital twin for leakage current model with experimental data
        Args:
            data: The training data, expected as a Pandas DataFrame
            batch_size (int): Training batch size
            epochs (int): Number of epochs for training
            learning_rate (float): Learning rate for training
            verbose (0 or 1): Verbosity of display while training
        """

請注意,任何瞭解構建深度學習模型的人都熟悉的參數,如batch_size、epochs和—。learning_rate作爲主要輸入,你只需要提供data ,一個 Pandas DataFrame。

在內部,代碼構建了一個 Tensorflow Keras 模型,對其進行編譯和訓練,並將訓練好的模型保存爲 Digital Twin 的內部屬性 ( self.leakage_model)。

# Deep-learning model
model = build_model(num_layers=3,
                    architecture=[32,32,32],
                    input_dim=3)
# Compile and train
model_trained = compile_train_model(model,
                                    X_train_scaled,
                                    y_train_scaled,
                                    batch_size=batch_size,
                                    epochs=epochs,
                                    learning_rate=learning_rate,
                                    verbose=verbose)
self.leakage_model = model_trained

像隱藏層的數量和激活函數這樣的超參數在這個實現中是預先固定的,但是它們可以很容易地暴露給在實際應用程序中使用數字孿生的開發人員。

數字孿生的美妙之處在於它允許你隨時將分析模型替換爲 ML 模型(反之亦然)

7.4 機器學習的數據源

對於這個演示,我們使用特殊的輔助函數(包含在Notebook中)創建了一些合成數據來訓練 DNN。該助手包括隨機變量,以模擬前面提到的製造和測量中的可變性和噪聲。

在這裏插入圖片描述

然而,在現實生活中,半導體工廠/晶圓廠將在數百萬個 MOSFET 上運行物理測試套件(使用其他機器),並記錄它們在各種 Vgs 偏置電壓下的泄漏電流。它還將記錄測試中這些 MOSFET 的 Vth。所有這些數據都將流入數字孿生模型,模型將被不斷訓練和更新。

在這裏插入圖片描述

通過這種安排,我們只需要編寫一行代碼來使用作爲dfDataFrame 提供的訓練數據來訓練模型:

mosfet.train_leakage(df)

熟悉的訓練開始了:

7.5 預測方法

我們編寫了一個單獨的泄漏方法來預測作爲輸入的跨導、Vgs 和 Vth 的任意組合的 sub-Vth 泄漏:

def leakage(self,
                w_l=1e-2,
                vgs=None,
                vth=None):
        """
        Calculates leakage current using the deep learning model
        """
        if not self._leakage_:
            return "Leakage model is not trained yet"
        # Vgs
        if vgs is None:
            vgs = self._terminals_['gate'] - self._terminals_['source']
        else:
            vgs = vgs
        # Vth
        if vth is None:
            vth = self._params_['Vth']
        else:
            vth = vth
        
        # Predict
        x = np.array([w_l,vgs,vth])
        ip = x.reshape(-1,3)
        result = float(10**(-self.leakage_model.predict(ip)))
        
        return result

代碼中的冪運算(提高到 10 次方)是因爲我們提供了實際泄漏值的負 10 對數作爲 DNN 模型的訓練目標。這樣做是爲了實現更快的收斂和更高的準確性。

8、結束語

在本文中,我們只是通過展示 Python 編程框架的一些簡單步驟來剝離數字孿生設計的上層。如何爲選擇的系統/資產添加更復雜的編程層、邏輯層和數據科學層,並設計強大的數字孿生,這還取決於讀者自己。

工業 4.0/智能工廠已經到來,並準備好利用數字化轉型、人工智能和機器學習方面的所有進步。數字孿生是這一旅程的重要組成部分。


原文鏈接:數字孿生Python實戰 — BimAnt

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章