首頁 > 軟體

Python實現將DNA序列儲存為tfr檔案並讀取流程介紹

2022-09-06 18:06:14

最近導師讓我跑模型,生物資訊方向的,我一個學計算機的,好多東西都看不明白。現在的方向大致是,用深度學習的模型預測病毒感染人類的風險。

既然是病毒,就需要拿到它的DNA,也就是鹼基序列,然後把這些ACGT序列丟進模型裡面,然後就是預測能不能感染人類,說實話,估計結果不會好,現在啥都是transformer,而且我看的這篇論文,我認為僅僅從DNA序列大概預測不出什麼東西。

但是就那樣吧,現在資料去哪裡下載,需要下載什麼樣的資料,下載完成後怎麼處理我還是一臉懵逼,但是假設上面都處理好了,然後即使把資料丟給模型,跑就完了。

也不是沒進度,目前瞭解到的是,我應該使用一種叫fasta格式的檔案,然後把裡面的一大串ACGT序列拿出來,轉為模型可以處理的資料。然後,以後再說。

現在假設我已經有了ACGT的序列,然後把它轉為模型可以處理的矩陣。

這裡,我隨機生成長度為131072的基因序列,為什麼是這個數位呢,因為這是之前看的 論文裡的值,,暫時按照這個來做。

實現:

首先是匯入庫

import numpy as np
import random
import tensorflow as tf
import inspect
from typing import Any, Callable, Dict, Optional, Text, Union, Iterable
import os

然後,定義一個生成長度為131072bp的函數:

#隨機生成131072的dna序列
length = 131072
def randomSeq(length):
  return ''.join([random.choice('ACGT') for i in range(length)])

這個函數的返回結果是長度為length的字串,類似ACGTTGC這樣。

然後這種序列模型是沒辦法處理的,所以需要把它變成矩陣,也就用one-hot編碼。

比如ACGT這個序列,編碼成:

[ [1,0,0,0],

[0,1,0,0],

[0,0,1,0],

[0,0,0,1] ]

這樣的一個矩陣,這個就不細說了,網上很多資料。

然後,我從別人的程式碼中抄了一個函數,很好用。

#DNA序列轉為one-hot編碼,可以直接拿來用
def one_hot_encode(sequence: str,
                   alphabet: str = 'ACGT',
                   neutral_alphabet: str = 'N',
                   neutral_value: Any = 0,
                   dtype=np.float32) -> np.ndarray:
  """One-hot encode sequence."""
  def to_uint8(string):
    return np.frombuffer(string.encode('ascii'), dtype=np.uint8)
  hash_table = np.zeros((np.iinfo(np.uint8).max, len(alphabet)), dtype=dtype)
  hash_table[to_uint8(alphabet)] = np.eye(len(alphabet), dtype=dtype)
  hash_table[to_uint8(neutral_alphabet)] = neutral_value
  hash_table = hash_table.astype(dtype)
  return hash_table[to_uint8(sequence)]

這是一個巢狀函數了,仔細研究下還是可以理解的,我就不說了,會用就行了。

簡單講一下引數的意思:

sequence:字串型別,就是輸入的鹼基序列。

alphabet: str = ‘ACGT’ :詞表,一共只需要這四個詞

neutral_alphabet: str = ‘N’,

neutral_value: Any = 0,

上面這兩一起用,就是說遇到N這個鹼基就會編碼成[0,0,0,0]的向量。

dtype=np.float32,這個就是內部元素值的型別。

簡單生成一下:

然後輸入序列長度是131072bp,所以輸入的矩陣就是131072x4的矩陣,現在來把序列變為矩陣。

編碼成one-hot矩陣

dnaVec = one_hot_encode(dna)

現在DNA序列已經變成了矩陣,接下來需要把這一條序列,也就是一個樣本資料,變成TensorFlow中的TFRecord檔案格式。TFRecord 是 TensorFlow 中的資料集儲存格式。當我們將資料集整理成 TFRecord 格式後,TensorFlow 就可以高效地讀取和處理這些資料集,從而幫助我們更高效地進行大規模的模型訓練。

關於tfr檔案的處理,我就不在細說了,總之現在我們需要構建example。

在此之前,我們需要先這麼做:

#給出結果的tfr檔案的路徑
path = '/content/drive/MyDrive/test_Enformer/result.tfr'
#dna的numpy陣列轉成位元組流,這樣才能儲存
dnaVec = dnaVec.tobytes()

接下來就是把這個位元組流資料寫入到tfr檔案中,這裡同時寫入這條資料的label中,我的問題是給一個Dna序列,預測是或者不是的二分類問題,所以我同時把這條dna序列對應的真實標籤也寫進去,但是我是隨機從0,1中選擇一個。

from tensorflow.core.example.feature_pb2 import BytesList
with tf.io.TFRecordWriter(path) as writer:
  feature = {
      #序列使用的是tf.train.BytesList型別
      'sequence':tf.train.Feature(bytes_list=tf.train.BytesList(value=[dnaVec])),
      #label是隨機生成的0,或者1
      'label':tf.train.Feature(int64_list=tf.train.Int64List(value=[np.random.choice([0,1])]))
  }
  example = tf.train.Example(features=tf.train.Features(feature=feature))
  writer.write(example.SerializeToString())

這部分的程式碼執行結束後,就已經把dna序列以及對應的標籤寫入了tfr檔案中,不過這個tfr檔案中只有一個example,你可以寫更多個。

剛剛寫入的tfr檔案

到這裡,相當於已經把資料準備好了,接下來就是讀取資料。

#從剛才的路徑中載入資料集
dataset = tf.data.TFRecordDataset(path)
#定義Feature結構,告訴解碼器每個Feature的型別是什麼
feature_description = {"sequence": tf.io.FixedLenFeature((), tf.string),
              "label": tf.io.FixedLenFeature((), tf.int64)}
 #將 TFRecord 檔案中的每一個序列化的 tf.train.Example 解碼
def parse_example(example_string):
  #解析之後得到的example
  example = tf.io.parse_single_example(example_string,feature_description)
  #example['sequence']還是位元組流的形式,重新轉為數位向量
  sequence = tf.io.decode_raw(example['sequence'], tf.float32)
  sequence = tf.reshape(sequence,(length,4))  #形狀需要重塑,不然就是一個長向量
  label = tf.cast(example['label'],tf.int64)  #標籤對應的型別轉換
#每一天example解析後返回對應的一個字典
  return {
      'sequence':sequence,
      'label': label
  }
#把parse_example函數對映到dataset中的每個example,
#這裡的dataset中只有一個example
dataset = dataset.map(parse_example)

此時的dataset是一個可以遍歷的物件,內部元素可以認為是解析完成後的example。

這個字典有兩個鍵sequence和lable,對應著序列矩陣和標籤值

這就是可以用來訓練的資料。

到此這篇關於Python實現將DNA序列儲存為tfr檔案並讀取流程介紹的文章就介紹到這了,更多相關Python儲存tfr檔案內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com