40行Python代碼,實現卷積特徵可視化

2020-12-06 機器之心Pro

選自towardsdatascience

作者:Fabio M. Graetz

機器之心編譯

機器之心編輯部

卷積神經網絡(CNN)變革了計算機視覺,並將徹底改變整個世界。因此,開發解釋 CNN 的技術也同樣是一個重要的研究領域。本文將向你解釋如何僅使用 40 行 Python 代碼將卷積特徵可視化。

最近在閱讀 Jeremy Rifkin 的書《The End of Work》時,我讀到一個有趣的關於 AI 的定義。Rifkin 寫到:「今天,當科學家們談論人工智慧時,他們通常是指『一門創造機器的藝術,該機器所執行的功能在人類執行時需要智能』(Kurzweil, Raymond, The Age of Intelligent Machines (Cambridge, MA: MIT Press, 1990), p. 14.)」。我很喜歡這個定義,因為它避免了類似」在人類智力意義上 AI 是否真正達到智能」的討論。

作為一名科學家,揭開大腦功能的基本原理並創造一個真正的智能機器的想法確實讓我很興奮,但是我認為認識到深度學習模型並不是大腦模型這一點非常重要。深度學習研究的目的是從數據中學習到目前為止還沒有自動化的流程的規則並實現自動化。雖然這聽起來並不是那麼讓人興奮,但它確實是一件好事。舉個例子:深度卷積神經網絡的出現徹底改變了計算機視覺和模式識別,這讓我們在醫療診斷中可以大量地引入自動化;人們可以加速為貧窮國家的人提供頂級醫療診斷,而不需要在本地培訓大量的醫生和專家。

儘管深度學習給人們帶來了許多振奮的消息,但它如何看待和解釋世界仍然是一個黑匣子。更好地理解它們如何識別特定的模式和對象,以及為什麼它們能夠表現地如此良好,可以讓我們:1)進一步改進它們;2)解決法律問題——因為在許多情況下機器所做出的決定必須能夠被人類所理解。

有兩種方法可以嘗試理解神經網絡如何識別某種模式。如果你想知道哪種模式可以顯著地激活某個特徵圖,你可以:1)嘗試在數據集中查找導致此特徵圖高於平均激活的圖像;2)嘗試通過優化隨機圖像中的像素值來生成這種模式。後者的想法是由 Erhan 等人提出的。

在本文中我將向你解釋如何僅用 40 行 Python 代碼來實現隨機圖像的像素值優化(如下圖),從而生成卷積神經網絡的特徵可視化。

本文的結構如下:首先,我將展示 VGG-16 網絡的幾個層次中的卷積特徵的可視化;然後,嘗試理解其中一些可視化,我將展示如何快速測試一個假設,即特定的濾波器會檢測到哪種模式;最後,我將解釋創建本文中提供的模式所需的代碼。

特徵可視化

神經網絡學習將輸入數據(如圖像)轉換為越來越有意義但表徵越來越複雜的連續層。

你可以將深度網絡看做一個多階段信息蒸餾操作,其中信息通過連續的濾波器並不斷被「提純」。(Franois Chollet, Deep Learning with Python (Shelter Island, NY: Manning Publications, 2018), p. 9)

閱讀完他的文章後,你將了解如何生成模式,以最大化這些層次表徵的某個層中所選特徵圖的平均激活,如何解釋其中一些可視化,以及最終如何測試所選濾波器可能響應的模式或紋理的假設。你可以在下面找到 VGG-16 網絡多個層中濾波器的特徵可視化。在查看它們時,希望你能觀察到生成模式的複雜性如何隨著進入網絡的深度而增加。

Layer 7: Conv2d(64, 128)

濾波器 12, 16, 86, 110(左上到右下,逐行)

Layer 14: Conv2d(128, 256)

濾波器 1, 6, 31, 32, 54, 77, 83, 97, 125, 158, 162, 190(左上到右下,逐行)

Layer 20: Conv2d(256, 256)

濾波器 3, 34, 39, 55, 62, 105, 115, 181, 231(左上到右下,逐行)

Layer 30: Conv2d(512, 512)

濾波器 54, 62, 67, 92, 123, 141, 150, 172, 180, 213, 233, 266, 277, 293, 331, 350, 421, 427(左上到右下,逐行)

Layer 40: Conv2d(512, 512)—top of the network

濾波器 4, 9, 34, 35, 75, 123, 150, 158, 203, 234, 246, 253, 256, 261, 265, 277, 286, 462(左上到右下,逐行)

這些模式讓我覺得非常震撼!部分原因是,它們太漂亮了,我都想立馬將它們裱起來掛在牆上;但主要的原因是,它們僅僅是通過最大化由數千張圖像訓練出的數學方程中的某個值得到的。在瀏覽通過最大化最後一層卷積層特徵圖的平均激活得到的 512 個模式時,我經常發出感慨「哇,這是一隻雞」,或「這不是一根羽毛嘛」。

識別模式

我們來嘗試解釋幾個可視化的特徵。從這個開始,有沒有讓你想起些什麼?

第 40 層第 286 個濾波器

這張照片立刻讓我想起了教堂拱形天花板的圓拱。

來,讓我們檢驗一下。人造的那張圖片是通過最大化第 40 層第 286 個特徵圖的平均激活創造出來的。我們來看看當把拱門的照片輸入網絡後,第 40 層特徵圖的平均激活會是怎樣:

看到了什麼?正如期望的那樣,特徵圖上的 286 處有一個極強的尖峰。所以,這是否意味著第 40 層第 286 個濾波器是負責檢測拱形天花板的呢?這裡我們要小心一點,濾波器 286 顯然會響應圖像中的拱形結構,但請記住,這樣的拱形結構可能會在幾個不同的類別中起到重要作用。

注意:雖然我使用第 40 層(卷積層)來生成我們當前正在查看的圖像,但我使用了第 42 層來生成顯示每個特徵圖的平均激活的圖。第 41 和 42 層是 batch-norm 和 ReLU。ReLU 激活函數刪除所有負值,選擇第 42 層而不是 40 的唯一原因是,後者將顯示大量負噪聲,這使得我們很難看到我們感興趣的正峰值。

再來一例。

第 40 層第 256 個濾波器

我敢保證,這些是雞頭(或者至少是鳥頭)!從圖中我們可以看到尖尖的喙和黑色的眼睛。我們可以用下面的這個圖片來檢驗:

類似地,特徵圖上的 256 處會出現強烈的尖峰:

再來:

第 40 層第 462 個濾波器

濾波器 462 會不會對羽毛作出反應呢?來,輸入一張羽毛圖片:

Yes!濾波器 462 果然反應強烈:

猜一猜濾波器 265 會對什麼產生響應?

第 40 層第 265 個濾波器

或許是鏈條吧?來,我們輸入一張試試:

Yes,看起來猜對了!

不過從上圖可以看到,除了最大的尖峰外,還有幾個較大的次尖峰。我們看看對應的第 95 和第 303 個特徵可視化圖是什麼:

第 40 層第 95 和第 303 個濾波器

再來看張比較酷的:

第 40 層第 64 個濾波器

有許多看起來像羽毛一樣的結構,似乎還有鳥腿,左下方有個類似鳥頭的東西。腿和喙顯然比雞的長,所以可能是一隻鳥。我們將下面這幅圖輸入網絡:

得到這樣的特徵圖:

好吧,,在 64 處確實有個尖峰,但好像有許多比它更高的。讓我們再來看看其中四個特徵尖峰對應的濾波器生成的模式:

第 40 層第 172 和第 288 個濾波器

第 40 層第 437 和第 495 個濾波器

上面兩幅(172、288)圖看起來似乎有更多腿和眼睛/喙;不過下面兩幅(437、495)我實在看不出它表示了什麼。也許這些模式與圖像的背景相關,或者只是代表網絡檢測到了一些我所不能理解的鳥類的信息。我想現在這個地方仍然是黑匣子的一部分。

再來最後一張,比較可愛,之後我們就直接進入代碼部分。你能猜到這個是什麼嗎?

第 40 層第 277 個濾波器

我擼貓多年,所以我立馬看到了毛茸茸的貓耳。左上角那個較大的最為明顯。好,讓我們輸入一張貓圖:

Yes,特徵圖上 277 處確實有一個強烈的尖峰,但是旁邊更強烈的尖峰是怎麼回事?

我們快速看下特徵圖 281 對應的模式圖:

第 40 層第 281 個濾波器

也許是條紋貓的皮毛?

對於從網絡中發現上述這樣的秘密,我簡直樂此不疲。但事實上,即使在最終的卷積層,大多數濾波器生成的模式對我來說還是非常抽象的。更為嚴格的方法應該是將網絡應用於整個包含許多不同種類圖像的數據集,並跟蹤在某一層中激發特定濾波器的圖像。

代碼詳解

思路大致如下:我們從包含隨機像素的圖片開始,將它輸入到評估模式的網絡中,計算特定層中某個特徵圖的平均激活,然後計算輸入圖像像素值的梯度;知道像素值的梯度後,我們繼續以最大化所選特徵圖的平均激活的方式更新像素值。

貌似這樣說不好理解,那我們換種方式:網絡權重是固定的,網絡也不會被訓練,我們試圖找到一個圖像,通過在像素值上執行梯度下降優化來最大化特定特徵圖的平均激活。

這個技術也叫做神經風格遷移。

為了實現這一點,我們需要:

從隨機圖像開始;評估模式下的預訓練網絡;一種訪問我們感興趣的任何隱藏層激活函數的方式;用於計算漸梯度的損失函數和用於更新像素值的優化器。

我們先來生成一張帶噪圖作為輸入。我們可以如下這樣做:

img = np.uint8(np.random.uniform(150, 180, (sz, sz, 3)))/255

其中 sz 是圖像的長、寬,3 是顏色通道數,我們除以 255 是因為 uint8 類型的變量最大值是 255。如果你想得到更多或更少的噪聲,可以修改 150 和 180。

然後我們用

img_var = V(img[None], requires_grad=True)

將之轉化為一個需要梯度的 PyTorch 變量。像素值需要梯度,因為我們要使用反向傳播來優化它們。

接著,我們需要一個評估模式下(意味著其權重是不變的)的預訓練網絡。這可以用如下代碼:

model = vgg16(pre=True).eval()set_trainable(model, False).

再然後,我們需要一種方式來獲取隱藏層的特徵。我們可以採用在我們感興趣的某個隱藏層後進行截斷的方式獲取,這樣該隱藏層就成了輸出層。不過在 PyTorch 中有一種更好的方法來解決這個問題,稱為」hook」,可以在 PyTorch 的 Module 或 Tensor 中說明。要理解這點,你需要知道:

PyTorch Module 是所有神經網絡模塊的基本類;我們的神經網絡的每個層都是一個 Module ;每個 Module 都有一個稱為 forward 的方法,當給 Module 一個輸入時它會計算輸出。

當我們將噪聲圖輸入到我們的網絡中時,forward 方法就會計算出第一層的輸出結果;第二層的輸入是前一層 forward 方法的輸出結果;以此類推。當我們在某個層「register forward hook」時,在該層的 forward 方法被調用後將執行「hook」。

例如,當我們對層 i 的特徵映射感興趣時,我們在 i 層 register 一個「forword hook」;當層 i 的 forward 方法被調用後,層 i 的特徵就會保存在一個變量裡。

保存變量的類如下:

classSaveFeatures():def__init__(self, module):self.hook= module.register_forward_hook(self.hook_fn) def hook_fn(self, module, input, output): self.features = torch.tensor(output,requires_grad=True).cuda() def close(self): self.hook.remove()

當執行 hook 時,調用方法 hook_fn。hook_fn 方法會將層輸出保存在 self.features。注意這個張量是需要梯度的,因為我們要在像素值上執行反向傳播。

怎麼用 SaveFeatures 對象呢?

對層 i 的 hook 為:

activations = SaveFeatures(list(self.model.children())[i])

當你用 model(img_var) 將模型應用到圖像上後,你可以通過 hook 保存在 activations.features 來訪問特徵。注意別忘了一點,在訪問完畢後使用 close 釋放內存。

好了,現在我們已經能夠訪問層 i 的特徵圖了。特徵圖的形式為 [ 1, 512, 7, 7 ],其中 1 表示批維度,512 表示濾波器/特徵圖的個數,7 表示特徵圖的長和寬。我們的目標就是最大化選擇的某一特徵圖 j 的平均激活值。因此我們定義如下損失函數:

loss = -activations.features[0, j].mean()

以及優化器:

optimizer = torch.optim.Adam([img_var], lr=lr, weight_decay=1e-6)

默認情況下,優化器可以最大限度地減少損失,因此我們只需將平均激活乘以 -1 即可告知優化器最大化損失。使用 optimizer.zero_grad() 重置梯度,使用 loss.backward() 計算像素值的梯度,並使用 optimizer.step() 更改像素值。

我們現在已經有了所有需要的東西:從隨機圖像開始,在評估模式下定義預先訓練的網絡,執行前向傳播以獲取第 i 層的特徵,並定義了允許我們更改像素值以最大化層 i 中特徵映射 j 的平均激活的優化器和損失函數。

好,讓我們看一個例子:

第 40 層,第 265 個濾波器

等等,這不正是我們想要的嗎?和前面的鏈條模式很相似;如果你眯著眼睛看,就可以看到鏈條。但可以肯定的是,我們獲得的特徵圖的局部性必定非常差,因此我們必須找到一種方法來指導我們的優化器以獲得最小化模式或者或「更好看」的模式。與我前面展示的模式相反,這張圖由高頻模式佔主導,類似於對抗樣本。那麼我們該怎麼解決這個問題呢?我嘗試了不同的優化器、學習速率以及正則化,但似乎沒有任何東西可以減少高頻模式。

接下來,我變化了一下輸入噪聲圖像的尺寸:

圖像大小分別為 200x200、300x300、400x400。

在這三幅圖中,有沒有發現「鏈狀圖案」的頻率隨著圖像尺寸的增加而增加?由於卷積濾波器具有固定的尺寸,因此當圖像解析度增大時,濾波器的相對尺寸就會變小。換句話說:假設創建的模式都是以像素為單位,當我們增加圖像尺寸,則生成圖案的相對尺寸將減小,而圖案的頻率將增加。

如果我的假設是正確的,那麼我們想要的是低解析度樣本(甚至比上面顯示的還低)但高分辨的低頻模式。這有意義嗎?以及怎麼做?

我的解決方案是:首先從非常低解析度的圖像開始,即 56×56 像素,優化像素值幾步,然後將圖像尺寸增加一定的係數;在對圖像放大後,再將像素值優化幾步;然後再次對圖像進行放大...

這樣獲得的結果出奇的好,一個低頻、高解析度、且沒有太多噪音的模式圖:

第 40 層,第 265 個濾波器。

我們現在有了一個解析度好得多的低頻模式,並且沒有太多的噪音。為什麼這樣做會有用呢?我的想法是:當我們從低解析度開始時,我們會得到低頻模式。放大後,放大後的模式圖相比直接用大尺度圖像優化生成的模式圖有較低的頻率。因此,在下一次迭代中優化像素值時,我們處於一個更好的起點,看起來避免了局部最小值。這有意義嗎?為了進一步減少高頻模式,我在放大後稍微模糊了圖像。

我發現以 1.2 的倍數放大 12 次之後得到的結果不錯。

看看下面的代碼。你會發現我們已經將重點信息都講清了,例如創建隨機圖像、register hook、定義優化器和損失函數,以及優化像素值。唯一重要的新內容是:1)將代碼封裝到一個類中;2)我們在優化像素值後將圖像放大了幾次。

classFilterVisualizer():def__init__(self, size=56, upscaling_steps=12, upscaling_factor=1.2): self.size, self.upscaling_steps, self.upscaling_factor = size, upscaling_steps, upscaling_factor self.model = vgg16(pre=True).cuda().eval() set_trainable(self.model, False) def visualize(self, layer, filter, lr=0.1, opt_steps=20, blur=None): sz = self.size img = np.uint8(np.random.uniform(150, 180, (sz, sz, 3)))/255 # generate random image activations = SaveFeatures(list(self.model.children())[layer]) # register hookfor _ in range(self.upscaling_steps): # scale the image up upscaling_steps times train_tfms, val_tfms = tfms_from_model(vgg16, sz) img_var = V(val_tfms(img)[None], requires_grad=True) # convert image to Variable that requires grad optimizer = torch.optim.Adam([img_var], lr=lr, weight_decay=1e-6)for n in range(opt_steps): # optimize pixel values for opt_steps times optimizer.zero_grad() self.model(img_var) loss = -activations.features[0, filter].mean() loss.backward() optimizer.step() img = val_tfms.denorm(img_var.data.cpu().numpy()[0].transpose(1,2,0)) self.output = img sz = int(self.upscaling_factor * sz) # calculate new image size img = cv2.resize(img, (sz, sz), interpolation = cv2.INTER_CUBIC) # scale image upif blur is not None: img = cv2.blur(img,(blur,blur)) # blur image to reduce high frequency patterns self.save(layer, filter) activations.close() def save(self, layer, filter): plt.imsave("layer_"+str(layer)+"_filter_"+str(filter)+".jpg", np.clip(self.output, 0, 1))

使用 FilterVisualizer :

layer = 40filter = 265FV = FilterVisualizer(size=56, upscaling_steps=12, upscaling_factor=1.2)FV.visualize(layer, filter, blur=5)

代碼默認使用英偉達的 GPU,如果沒有,可以在 google colab 上測試。

原文連結:https://towardsdatascience.com/how-to-visualize-convolutional-features-in-40-lines-of-code-70b7d87b0030

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權

相關焦點

  • PyTorch可視化理解卷積神經網絡
    如今,機器已經能夠在理解、識別圖像中的特徵和對象等領域實現99%級別的準確率。生活中,我們每天都會運用到這一點,比如,智慧型手機拍照的時候能夠識別臉部、在類似於谷歌搜圖中搜索特定照片、從條形碼掃描文本或掃描書籍等。造就機器能夠獲得在這些視覺方面取得優異性能可能是源於一種特定類型的神經網絡——卷積神經網絡(CNN)。
  • 數字黑洞:python-matplotlib來實現可視化
    1.2 數字黑洞與python-matplotlib可視化1.2.4 python-matplotlib可視化來看看效果:pic4:n=481359246(後十位數值)規律:最後10個數值:13-40want to show:')) if n==0: print('----math black hole program have been stopped----') break while n>1: n=black(n) print(n)2.2 完整版matplotlib可視化代碼
  • Python語言中使用pyqtgraph庫實現數據可視化
    背景在Python程式語言中,matplotlib是一種常用的用於數據可視化的繪圖庫,它提供了一套和matlab相似的命令API,開發者可以僅需幾行代碼,便可生成如直方圖,功率譜,條形圖,錯誤圖,散點圖等圖形,適用於交互式繪圖,而且也可以方便地將它作為繪圖控制項嵌入到GUI應用程式中
  • 超硬核的 Python 數據可視化教程!
    Python實現可視化的三個步驟:確定問題,選擇圖形 轉換數據,應用函數 參數設置,一目了然 1、首先,要知道我們用哪些庫來畫圖?matplotlibpython中最基本的作圖庫就是matplotlib,是一個最基礎的Python可視化庫,一般都是從matplotlib上手Python數據可視化,然後開始做縱向與橫向拓展。
  • 20行Python代碼實現視頻字符化
    看起來是非常高端,但是實際實現起來確實非常簡單,我們只需要接觸opencv模塊,就能很快的實現視頻字符化。 OpenCV的安裝及圖片讀取 在Python中我們只需要用pip安裝即可,我們在控制臺執行下列語句: pip install opencv-python 安裝完成就可以開始使用
  • 10行Python代碼也能實現,親測好用!
    大數據文摘出品編譯:朱一輝、雪清、小魚短短10行代碼就可以實現目標檢測?!本文作者和他的團隊構建了一個名為ImageAI 的Python庫,集成了現今流行的深度學習框架和計算機視覺庫。本文將手把手教你構建自己的第一個目標檢測應用,而且文摘菌已經幫你踩過坑了,親測有效!
  • 機器學習、深度學習算法原理與案例實踐暨Python大數據綜合應用...
    共4天8節,講解機器學習和深度學習的模型理論和代碼實踐,梳理機器學習、深度學習、計算機視覺的技術框架,從根本上解決如何使用模型、優化模型的問題;每次課中,首先闡述算法理論和少量公式推導,然後使用真實數據做數據挖掘、機器學習、深度學習的數據分析、特徵選擇、調參和結果比較。
  • 運用sklearn進行線性判別分析(LDA)代碼實現
    基於sklearn的線性判別分析(LDA)代碼實現一、前言及回顧本文記錄使用sklearn庫實現有監督的數據降維技術——線性判別分析(LDA)。在上一篇LDA線性判別分析原理及python應用(葡萄酒案例分析),我們通過詳細的步驟理解LDA內部邏輯實現原理,能夠更好地掌握線性判別分析的內部機制。
  • 幾行代碼教你在Pytorch和Python中實現神經風格遷移
    從左到右為:內容圖像、風格圖像、生成的圖像這個方法相當直觀,本文是在pytorch和python中實現神經風格遷移的簡單指南,並預先解釋了這個方法。這些定義有助於理解目的,但實際上,實現該算法需要更精確的定義。可以使用下面概述的標準圖像分類網絡獲得這些定量定義。卷積神經網絡(CNN)是圖像分類的常用方法。為了進行分類,CNN將圖像作為輸入,並應用一組卷積濾波器、最大池化和非線性激活來給出更密集的輸入圖像表示。
  • 1行代碼實現Python數據分析:圖表美觀清晰,自帶對比功能丨開源
    現在,GitHub上一位博主告訴你:不用學,用sweetviz就行。這是一個基於Python編寫的數據分析軟體,只要掌握3種函數用法,一行Python代碼就能實現數據集可視化、分析與比較。我們以Titanic數據集為例,輸入一行代碼:一個1080p的清晰網頁界面就出現在了眼前。
  • 使用biopython可視化染色體和基因元件
    在biopython中,通過BiolGraphics子模塊可以對基因組結構進行可視化,支持線性和圈圖兩種可視化方式。其中,基因組結構信息存儲在genebank格式的文件中,首先通過Bio.SeqIO讀取結構信息,然後通過Bio.Graphics模塊進行可視化。
  • 程式設計師的樂趣,生成自定義二維碼,5行Python代碼就搞定
    那麼有沒有辦法實現自定義生成二維碼呢?近日,一位熱衷於終身學習的工程師兼攝影師 Arindom Bhattacharjee 撰寫了一篇自定義生成二維碼的方法,並且整個生成過程只需要 5 行 Python 代碼即可完成。感興趣的讀者可以自己實現下。
  • 有這5小段代碼在手,輕鬆實現數據可視化(Python+Matplotlib)
    大數據文摘作品編譯:傅一洋、吳雙、龍牧雪本文要講的是Matplotlib,一個強大的Python可視化庫。一共5小段代碼,輕鬆實現散點圖、折線圖、直方圖、柱狀圖、箱線圖,每段代碼只有10行,也是再簡單不過了吧!數據可視化是數據科學家工作的一項主要任務。
  • CNN 模型的可視化
    大家都了解卷積神經網絡 CNN,但是對於它在每一層提取到的特徵以及訓練的過程可能還是不太明白,所以這篇主要通過模型的可視化來神經網絡在每一層中是如何訓練的。我們知道,神經網絡本身包含了一系列特徵提取器,理想的 feature map 應該是稀疏的以及包含典型的局部信息。
  • 3行代碼Python搞定圖片清晰度識別,原來我們看到不一定是真的
    Pech-Pacheco 在 2000 年模式識別國際會議提出將圖片中某一通道(一般用灰度值)通過拉普拉斯掩模做卷積運算,然後計算標準差,出來的值就可以代表圖片清晰度。這種方法湊效的原因就在於拉普拉斯算子定義本身。它被用來測量圖片的二階導數,突出圖片中強度快速變化的區域,和 Sobel 以及 Scharr 算子十分相似。
  • Capsule官方代碼開源之後,機器之心做了份核心代碼解讀
    前幾天,Sara Sabour 開源了一份 Capsule 代碼,該代碼是論文 Dynamic Routing between Capsules 中所採用的實現。其實早在去年剛公布此論文,機器之心就曾詳解解讀過核心思想與基本代碼,我們採用的代碼也是各研究者嘗試復現論文結果的模型。
  • 使用模板匹配在Python上進行對象檢測!(附代碼)
    要寫的是python代碼,以顯示此模板圖像實際適合我的源圖像的所有區域。首先,讓我們開始檢測一個對象,其次,我們可以調整代碼以檢測多個對象。檢測一個物體-最準確的物體為此,我們需要一個源圖像和一個模板圖像。
  • CVPR 2019 | PointConv:在點雲上高效實現卷積操作
    3D 點的相對坐標 P_local 經過連續函數 MLP1 之後可以得到對應的每一個點的特徵的權重 W;而密度 Density 經過 MLP2 之後得到逆密度係數 S;在得到權重 W, 逆密度係數 S 以及輸入的特徵 F 之後,可以利用下式進行卷積,以得到輸出特徵 F_out:PointConv 通過學習連續的卷積核函數,適應了 3D 點雲的不規則的特性,實現了置換不變性,使得卷積操作由傳統的圖像擴展到了
  • 應用BioPython解析和可視化蛋白質的結構
    今日我們以Python語言為基礎,調用BioPython框架/模塊,以2003年SARS冠狀病毒的刺突蛋白(spike protein)為例子來實現蛋白質的解析與可視化。現在很多生物信息學家、基礎和臨床醫學研究者喜歡使用Python來編程,而調用BioPython模塊/框架可以節省很多時間和精力來實現想要的生物信息學算法。今天咱們就使用BioPython模塊來解析和可視化蛋白質分子。
  • 50 行代碼,實現中英文翻譯
    雖然現在有非常多的翻譯軟體,但通過自己動手寫個 python 小程序,是非常的有成就感。甚至你藉助今天的代碼,也可以自己開發個小型翻譯軟體。有道詞典接口今天的翻譯程序是借用有道翻譯的接口來實現的。程序代碼程序代碼很簡單,在相應的代碼裡我都有注釋。