當前位置:首頁 » 編程語言 » pythoncolorbar

pythoncolorbar

發布時間: 2023-09-28 22:55:44

1. 聲線年齡層怎麼劃分

從EDA、音頻預處理到特徵工程和數據建模的完整源代碼演示
大多數人都熟悉如何在圖像、文本或表格數據上運行數據科學項目。 但處理音頻數據的樣例非常的少見。 在本文中,將介紹如何在機器學習的幫助下准備、探索和分析音頻數據。 簡而言之:與其他的形式(例如文本或圖像)類似我們需要將音頻數據轉換為機器可識別的格式。
音頻數據的有趣之處在於您可以將其視為多種不同的模式:
· 可以提取高級特徵並分析表格數據等數據。
· 可以計算頻率圖並分析圖像數據等數據。
· 可以使用時間敏感模型並分析時間序列數據等數據。
· 可以使用語音到文本模型並像文本數據一樣分析數據。
在本文中,我們將介紹前三種方法。 首先看看音頻數據的實際樣子。

音頻數據的格式

雖然有多個 python 庫可以處理音頻數據,但我們推薦使用 librosa。 讓我們載入一個 MP3 文件並繪制它的內容。
# Import librosa
import librosa
# Loads mp3 file with a specific sampling rate, here 16kHz
y, sr = librosa.load("c4_sample-1.mp3", sr=16_000)
# Plot the signal stored in 'y'
from matplotlib import pyplot as plt
import librosa.display
plt.figure(figsize=(12, 3))
plt.title("Audio signal as waveform")
librosa.display.waveplot(y, sr=sr);
這里看到的是句子的波形表示。
1、波形 - 信號的時域表示
之前稱它為時間序列數據,但現在我們稱它為波形? 當只看這個音頻文件的一小部分時,這一點變得更加清晰。 下圖顯示了與上面相同的內容,但這次只有 62.5 毫秒。
我們看到的是一個時間信號,它以不同的頻率和幅度在值 0 附近振盪。該信號表示氣壓隨時間的變化,或揚聲器膜(或耳膜)的物理位移 . 這就是為什麼這種對音頻數據的描述也稱為波形的原因。
頻率是該信號振盪的速度。 低頻例如 60 Hz 可能是低音吉他的聲音,而鳥兒的歌聲可能是 8000 Hz 的更高頻率。 我們人類語言通常介於兩者之間。
要知道這個信號在單位時間內從連續信號中提取並組成離散信號的采樣個數,我們使用赫茲(Hz)來表示每秒的采樣個數。 16'000 或 16k Hz表示美標採集了16000次。 我們在上圖中可以看到的 1'000 個時間點代表了 62.5 毫秒(1000/16000 = 0.0625)的音頻信號。
2、傅里葉變換——信號的頻域表示
雖然之前的可視化可以告訴我們什麼時候發生了(即 2 秒左右似乎有很多波形信號),但它不能真正告訴我們它發生的頻率。 因為波形向我們顯示了有關時間的信息,所以該信號也被稱為信號的時域表示。
可以使用快速傅立葉變換,反轉這個問題並獲得關於存在哪些頻率的信息,同時丟棄掉關於時間的信息。 在這種情況下,信號表示被稱為信號的頻域表示。
讓我們看看之前的句子在頻域中的表現。
import scipy
import numpy as np
# Applies fast fourier transformation to the signal and takes absolute values
y_freq = np.abs(scipy.fftpack.fft(y))
# Establishes all possible frequency
# (dependent on the sampling rate and the length of the signal)
f = np.linspace(0, sr, len(y_freq))
# Plot audio signal as frequency information.
plt.figure(figsize=(12, 3))
plt.semilogx(f[: len(f) // 2], y_freq[: len(f) // 2])
plt.xlabel("Frequency (Hz)")
plt.show();
可以在此處看到大部分信號在 ~100 到 ~1000 Hz 之間(即 10² 到 10³ 之間)。 另外,似乎還有一些從 1'000 到 10'000 Hz 的內容。
3、頻譜圖
我們並不總是需要決定時域或頻域。 使用頻譜圖同時表示這兩個領域中的信息,同時將它們的大部差別保持在最低限度。 有多種方法可以創建頻譜圖,但在本文中將介紹常見的三種。
3a 短時傅里葉變換 (STFT)
這時是之前的快速傅立葉變換的小型改編版本,即短時傅立葉變換 (STFT), 這種方式是以滑動窗口的方式計算多個小時間窗口(因此稱為「短時傅立葉」)的 FFT。
import librosa.display
# Compute short-time Fourier Transform
x_stft = np.abs(librosa.stft(y))
# Apply logarithmic dB-scale to spectrogram and set maximum to 0 dB
x_stft = librosa.amplitude_to_db(x_stft, ref=np.max)
# Plot STFT spectrogram
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_stft, sr=sr, x_axis="time", y_axis="log")
plt.colorbar(format="%+2.0f dB")
plt.show();
與所有頻譜圖一樣,顏色代表在給定時間點給定頻率的量(響度/音量)。 +0dB 是最響亮的,-80dB 接近靜音。 在水平 x 軸上我們可以看到時間,而在垂直 y 軸上我們可以看到不同的頻率。
3b 梅爾譜圖
作為 STFT 的替代方案,還可以計算基於 mel 標度的梅爾頻譜圖。 這個尺度解釋了我們人類感知聲音音高的方式。 計算 mel 標度,以便人類將由 mel 標度中的 delta 隔開的兩對頻率感知為具有相同的感知差異。
梅爾譜圖的計算與 STFT 非常相似,主要區別在於 y 軸使用不同的刻度。
# Compute the mel spectrogram
x_mel = librosa.feature.melspectrogram(y=y, sr=sr)
# Apply logarithmic dB-scale to spectrogram and set maximum to 0 dB
x_mel = librosa.power_to_db(x_mel, ref=np.max)
# Plot mel spectrogram
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_mel, sr=sr, x_axis="time", y_axis="mel")
plt.colorbar(format="%+2.0f dB")
plt.show();
與 STFT 的區別可能不太明顯,但如果仔細觀察,就會發現在 STFT 圖中,從 0 到 512 Hz 的頻率在 y 軸上佔用的空間比在 mel 圖中要大得多 .
3c 梅爾頻率倒譜系數 (MFCC)
梅爾頻率倒譜系數 (MFCC) 是上面梅爾頻譜圖的替代表示。 MFCC 相對於 梅爾譜圖的優勢在於特徵數量相當少(即獨特的水平線標度),通常約為 20。
由於梅爾頻譜圖更接近我們人類感知音高的方式,並且 MFCC 只有少數幾個分量特徵,所以大多數機器學習從業者更喜歡 使用MFCC 以「圖像方式」表示音頻數據。 但是對於某些問題,STFT、mel 或波形表示可能會更好。
讓我們繼續計算 MFCC 並繪制它們。
# Extract 'n_mfcc' numbers of MFCCs components (here 20)
x_mfccs = librosa.feature.mfcc(y, sr=sr, n_mfcc=20)
# Plot MFCCs
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_mfccs, sr=sr, x_axis="time")
plt.colorbar()
plt.show();

數據清洗

現在我們更好地理解了音頻數據的樣子,讓我們可視化更多示例。
在這四個示例中,我們可以收集到有關此音頻數據集的更多問題:
· 大多數錄音在錄音的開頭和結尾都有一段較長的靜默期(示例 1 和示例 2)。 這是我們在「修剪」時應該注意的事情。
· 在某些情況下,由於按下和釋放錄制按鈕,這些靜音期會被「點擊」中斷(參見示例 2)。
· 一些錄音沒有這樣的靜音階段,即一條直線(示例 3 和 4)。
· 在收聽這些錄音時,有大量背景噪音。
為了更好地理解這在頻域中是如何表示的,讓我們看一下相應的 STFT 頻譜圖。
當聽錄音時,可以觀察到樣本 3 具有覆蓋多個頻率的不同背景雜訊,而樣本 4 中的背景雜訊相當恆定。 這也是我們在上圖中看到的。 樣本 3 在整個過程中都非常嘈雜,而樣本 4 僅在幾個頻率上(即粗水平線)有雜訊。 我們不會詳細討論如何消除這種噪音,因為這超出了本文的范圍。
但是讓我們研究一下如何消除此類噪音並修剪音頻樣本的「捷徑」。 雖然使用自定義過濾函數的更手動的方法可能是從音頻數據中去除雜訊的最佳方法,但在我們的例子中,將推薦使用實用的 python 包 noiserece。
import noiserece as nr
from scipy.io import wavfile
# Loop through all four samples
for i in range(4):
# Load audio file
fname = "c4_sample-%d.mp3" % (i + 1)
y, sr = librosa.load(fname, sr=16_000)
# Remove noise from audio sample
reced_noise = nr.rece_noise(y=y, sr=sr, stationary=False)
# Save output in a wav file as mp3 cannot be saved to directly
wavfile.write(fname.replace(".mp3", ".wav"), sr, reced_noise)
聆聽創建的 wav 文件,可以聽到噪音幾乎完全消失了。 雖然我們還引入了更多的代碼,但總的來說我們的去噪方法利大於弊。
對於修剪步驟,可以使用 librosa 的 .effects.trim() 函數。每個數據集可能需要一個不同的 top_db 參數來進行修剪,所以最好進行測試,看看哪個參數值好用。 在這個的例子中,它是 top_db=20。
# Loop through all four samples
for i in range(4):
# Load audio file
fname = "c4_sample-%d.wav" % (i + 1)
y, sr = librosa.load(fname, sr=16_000)
# Trim signal
y_trim, _ = librosa.effects.trim(y, top_db=20)
# Overwrite previous wav file
wavfile.write(fname.replace(".mp3", ".wav"), sr, y_trim)
現在讓我們再看一下清理後的數據。
看樣子好多了

特徵提取

數據是干凈的,應該繼續研究可以提取的特定於音頻的特徵了。
1、開始檢測
通過觀察一個信號的波形,librosa可以很好地識別一個新口語單詞的開始。
# Extract onset timestamps of words
onsets = librosa.onset.onset_detect(
y=y, sr=sr, units="time", hop_length=128, backtrack=False)
# Plot onsets together with waveform plot
plt.figure(figsize=(8, 3))
librosa.display.waveplot(y, sr=sr, alpha=0.2, x_axis="time")
for o in onsets:
plt.vlines(o, -0.5, 0.5, colors="r")
plt.show()
# Return number of onsets
number_of_words = len(onsets)
print(f"{number_of_words} onsets were detected in this audio signal.")
>>> 7 onsets were detected in this audio signal
2、錄音的長度
與此密切相關的是錄音的長度。錄音越長,能說的單詞就越多。所以計算一下錄音的長度和單詞被說出的速度。
ration = len(y) / sr
words_per_second = number_of_words / ration
print(f"""The audio signal is {ration:.2f} seconds long,
with an average of {words_per_second:.2f} words per seconds.""")
>>> The audio signal is 1.70 seconds long,
>>> with an average of 4.13 words per seconds.
3、節奏
語言是一種非常悅耳的信號,每個人都有自己獨特的說話方式和語速。因此,可以提取的另一個特徵是說話的節奏,即在音頻信號中可以檢測到的節拍數。
# Computes the tempo of a audio recording
tempo = librosa.beat.tempo(y, sr, start_bpm=10)[0]
print(f"The audio signal has a speed of {tempo:.2f} bpm.")
>>> The audio signal has a speed of 42.61 bpm.
4、基頻
基頻是周期聲音出現時的最低頻率。在音樂中也被稱為音高。在之前看到的譜圖圖中,基頻(也稱為f0)是圖像中最低的亮水平條帶。而在這個基本音之上的帶狀圖案的重復稱為諧波。
為了更好地說明確切意思,下面提取基頻,並在譜圖中畫出它們。
# Extract fundamental frequency using a probabilistic approach
f0, _, _ = librosa.pyin(y, sr=sr, fmin=10, fmax=8000, frame_length=1024)
# Establish timepoint of f0 signal
timepoints = np.linspace(0, ration, num=len(f0), endpoint=False)
# Plot fundamental frequency in spectrogram plot
plt.figure(figsize=(8, 3))
x_stft = np.abs(librosa.stft(y))
x_stft = librosa.amplitude_to_db(x_stft, ref=np.max)
librosa.display.specshow(x_stft, sr=sr, x_axis="time", y_axis="log")
plt.plot(timepoints, f0, color="cyan", linewidth=4)
plt.show();
在 100 Hz 附近看到的綠線是基本頻率。 但是如何將其用於特徵工程呢? 可以做的是計算這個 f0 的具體特徵。
# Computes mean, median, 5%- and 95%-percentile value of fundamental frequency
f0_values = [
np.nanmean(f0),
np.nanmedian(f0),
np.nanstd(f0),
np.nanpercentile(f0, 5),
np.nanpercentile(f0, 95),
]
print("""This audio signal has a mean of {:.2f}, a median of {:.2f}, a
std of {:.2f}, a 5-percentile at {:.2f} and a 95-percentile at {:.2f}.""".format(*f0_values))
>>> This audio signal has a mean of 81.98, a median of 80.46, a
>>> std of 4.42, a 5-percentile at 76.57 and a 95-percentile at 90.64.
除以上說的技術意外,還有更多可以探索的音頻特徵提取技術,這里就不詳細說明了。

音頻數據集的探索性數據分析 (EDA)

現在我們知道了音頻數據是什麼樣子以及如何處理它,讓我們對它進行適當的 EDA。 首先下載一個數據集Kaggle 的 Common Voice 。 這個 14 GB 的大數據集只是來自 Mozilla 的 +70 GB 大數據集的一個小的快照。 對於本文這里的示例,將只使用這個數據集的大約 9'000 個音頻文件的子樣本。
看看這個數據集和一些已經提取的特徵。
1、特徵分布調查
目標類別年齡和性別的類別分布。
目標類別分布是不平衡的
下一步,讓我們仔細看看提取的特徵的值分布。
除了 words_per_second,這些特徵分布中的大多數都是右偏的,因此可以從對數轉換中獲益。
import numpy as np
# Applies log1p on features that are not age, gender, filename or words_per_second
df = df.apply(
lambda x: np.log1p(x)
if x.name not in ["age", "gender", "filename", "words_per_second"]
else x)
# Let's look at the distribution once more
df.drop(columns=["age", "gender", "filename"]).hist(
bins=100, figsize=(14, 10))
plt.show();
好多了,但有趣的是 f0 特徵似乎都具有雙峰分布。 讓我們繪制與以前相同的內容,但這次按性別分開。
正如懷疑的那樣,這里似乎存在性別效應! 但也可以看到,一些 f0 分數(這里特別是男性)比應有的低和高得多。 由於特徵提取不良,這些可能是異常值。 仔細看看下圖的所有數據點。
# Plot sample points for each feature indivially
df.plot(lw=0, marker=".", subplots=True, layout=(-1, 3),
figsize=(15, 7.5), markersize=2)
plt.tight_layout()
plt.show();
鑒於特徵的數量很少,而且有相當漂亮的帶有明顯尾部的分布,可以遍歷它們中的每一個,並逐個特徵地確定異常值截止閾值。
2、特徵的相關性
下一步,看看所有特徵之間的相關性。 但在這樣做之前需要對非數字目標特徵進行編碼。 可以使用 scikit-learn 的 OrdinalEncoder 來執行此操作,但這可能會破壞年齡特徵中的正確順序。 因此在這裏手動進行映射。
# Map age to appropriate numerical value
df.loc[:, "age"] = df["age"].map({
"teens": 0,
"twenties": 1,
"thirties": 2,
"fourties": 3,
"fifties": 4,
"sixties": 5})
# Map gender to corresponding numerical value
df.loc[:, "gender"] = df["gender"].map({"male": 0, "female": 1})
現在可以使用 pandas 的 .corr() 函數和 seaborn 的 heatmap() 來更深入地了解特徵相關性。
import seaborn as sns
plt.figure(figsize=(8, 8))
df_corr = df.corr() * 100
sns.heatmap(df_corr, square=True, annot=True, fmt=".0f",
mask=np.eye(len(df_corr)), center=0)
plt.show();
非常有趣!提取的 f0 特徵似乎與性別目標有相當強的關系,而年齡似乎與任何其他的特徵都沒有太大的相關性。
3、頻譜圖特徵
目前還沒有查看實際錄音。 正如之前看到的,有很多選擇(即波形或 STFT、mel 或 mfccs 頻譜圖)。
音頻樣本的長度都不同,這意味著頻譜圖也會有不同的長度。 因此為了標准化所有錄音,首先要將它們剪切到正好 3 秒的長度:太短的樣本會被填充,而太長的樣本會被剪掉。
一旦計算了所有這些頻譜圖,我們就可以繼續對它們執行一些 EDA! 而且因為看到「性別」似乎與錄音有特殊的關系,所以分別可視化兩種性別的平均梅爾譜圖,以及它們的差異。
男性說話者的平均聲音低於女性。 這可以通過差異圖中的較低頻率(在紅色水平區域中看到)的更多強度來看出。

模型選擇

現在已經可以進行建模了。我們有多種選擇。關於模型,我們可以……
· 訓練我們經典(即淺層)機器學習模型,例如 LogisticRegression 或 SVC。
· 訓練深度學習模型,即深度神經網路。
· 使用 TensorflowHub 的預訓練神經網路進行特徵提取,然後在這些高級特徵上訓練淺層或深層模型
而我們訓練的數據是
· CSV 文件中的數據,將其與頻譜圖中的「mel 強度」特徵相結合,並將數據視為表格數據集
· 單獨的梅爾譜圖並將它們視為圖像數據集
· 使用TensorflowHub現有模型提取的高級特徵,將它們與其他表格數據結合起來,並將其視為表格數據集
當然,有許多不同的方法和其他方法可以為建模部分創建數據集。因為我們沒有使用全量的數據,所以在本文我們使用最簡單的機器學習模型。

經典(即淺層)機器學習模型

這里使用EDA獲取數據,與一個簡單的 LogisticRegression 模型結合起來,看看我們能在多大程度上預測說話者的年齡。除此以外還使用 GridSearchCV 來探索不同的超參數組合,以及執行交叉驗證。
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import RobustScaler, PowerTransformer, QuantileTransformer
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
# Create pipeline
pipe = Pipeline(
[
("scaler", RobustScaler()),
("pca", PCA()),
("logreg", LogisticRegression(class_weight="balanced")),
]
)
# Create grid
grid = {
"scaler": [RobustScaler(), PowerTransformer(), QuantileTransformer()],
"pca": [None, PCA(0.99)],
"logreg__C": np.logspace(-3, 2, num=16),
}
# Create GridSearchCV
grid_cv = GridSearchCV(pipe, grid, cv=4, return_train_score=True, verbose=1)
# Train GridSearchCV
model = grid_cv.fit(x_tr, y_tr)
# Collect results in a DataFrame
cv_results = pd.DataFrame(grid_cv.cv_results_)
# Select the columns we are interested in
col_of_interest = [
"param_scaler",
"param_pca",
"param_logreg__C",
"mean_test_score",
"mean_train_score",
"std_test_score",
"std_train_score",
]
cv_results = cv_results[col_of_interest]
# Show the dataframe sorted according to our performance metric
cv_results.sort_values("mean_test_score", ascending=False)
作為上述 DataFrame 輸出的補充,還可以將性能得分繪制為探索的超參數的函數。 但是因為使用了有多個縮放器和 PCA ,所以需要為每個單獨的超參數組合創建一個單獨的圖。
在圖中,可以看到總體而言模型的表現同樣出色。 當降低 C 的值時,有些會出現更快的「下降」,而另一些則顯示訓練和測試(這里實際上是驗證)分數之間的差距更大,尤其是當我們不使用 PCA 時。
下面使用 best_estimator_ 模型,看看它在保留的測試集上的表現如何。
# Compute score of the best model on the withheld test set
best_clf = model.best_estimator_
best_clf.score(x_te, y_te)
>>> 0.4354094579008074
這已經是一個很好的成績了。 但是為了更好地理解分類模型的表現如何,可以列印相應的混淆矩陣。
雖然該模型能夠檢測到比其他模型更多的 20 歲樣本(左混淆矩陣),但總體而言,它實際上在對 10 歲和 60 歲的條目進行分類方面效果更好(例如,准確率分別為 59% 和 55%)。

總結

在這篇文章中,首先看到了音頻數據是什麼樣的,然後可以將其轉換成哪些不同的形式,如何對其進行清理和探索,最後如何將其用於訓練一些機器學習模型。如果您有任何問題,請隨時發表評論。
最後本文的源代碼在這里下載:
https://www.overfit.cn/post/
作者:Michael Notter

2. python plt可視化時,怎麼實現散點圖或者其他圖畫圖時,數據中相同點越多該點畫在圖上的顏色越深

你可以添加一個判斷語句,如果某個點數量比較多,就給這個點設置為深色,這里設置顏色你可以參考colorbar。
另外一種策略,你需要設置圖片中點的透明度,然後設置顏色為淺色調。如果不設置透明度,plt畫圖默認是沒有透明度的,多個點顏色並不會疊加而只會覆蓋,所以你需要設置恰當的透明度,讓多個點顏色可以疊加。具體的參數你可以去「CSDN」論壇搜索。

3. 如何用python畫好confusion matrix

在做分類的時候,經常需要畫混淆矩陣,下面我們使用python的matplotlib包,scikit-learning機器學習庫也同樣提供了例子:, 但是這樣的圖並不能滿足我們的要求,

首先是刻度的顯示是在方格的中間,這需要隱藏刻度,其次是如何把每個label顯示在每個方塊的中間, 其次是如何在每個方格中顯示accuracy數值, 最後是如何在橫坐標和縱坐標顯示label的名字,在label name比較長的時候,如何處理顯示問題。

直接貼上代碼:

[python]view plain

  • '''''computeconfusionmatrix

  • labels.txt:containlabelname.

  • predict.txt:predict_labeltrue_label

  • '''

  • fromsklearn.metricsimportconfusion_matrix

  • importmatplotlib.pyplotasplt

  • importnumpyasnp

  • #loadlabels.

  • labels=[]

  • file=open('labels.txt','r')

  • lines=file.readlines()

  • forlineinlines:

  • labels.append(line.strip())

  • file.close()

  • y_true=[]

  • y_pred=[]

  • #loadtrueandpredictlabels.

  • file=open('predict.txt','r')

  • lines=file.readlines()

  • forlineinlines:

  • y_true.append(int(line.split("")[1].strip()))

  • y_pred.append(int(line.split("")[0].strip()))

  • file.close()

  • tick_marks=np.array(range(len(labels)))+0.5

  • defplot_confusion_matrix(cm,title='ConfusionMatrix',cmap=plt.cm.binary):

  • plt.imshow(cm,interpolation='nearest',cmap=cmap)

  • plt.title(title)

  • plt.colorbar()

  • xlocations=np.array(range(len(labels)))

  • plt.xticks(xlocations,labels,rotation=90)

  • plt.yticks(xlocations,labels)

  • plt.ylabel('Truelabel')

  • plt.xlabel('Predictedlabel')

  • cm=confusion_matrix(y_true,y_pred)

  • printcm

  • np.set_printoptions(precision=2)

  • cm_normalized=cm.astype('float')/cm.sum(axis=1)[:,np.newaxis]

  • printcm_normalized

  • plt.figure(figsize=(12,8),dpi=120)

  • #setthefontsizeoflabel.

  • #forlabelinplt.gca().xaxis.get_ticklabels():

  • #label.set_fontsize(8)

  • #textportion

  • ind_array=np.arange(len(labels))

  • x,y=np.meshgrid(ind_array,ind_array)

  • forx_val,y_valinzip(x.flatten(),y.flatten()):

  • c=cm_normalized[y_val][x_val]

  • if(c>0.01):

  • plt.text(x_val,y_val,"%0.2f"%(c,),color='red',fontsize=7,va='center',ha='center')

  • #offsetthetick

  • plt.gca().set_xticks(tick_marks,minor=True)

  • plt.gca().set_yticks(tick_marks,minor=True)

  • plt.gca().xaxis.set_ticks_position('none')

  • plt.gca().yaxis.set_ticks_position('none')

  • plt.grid(True,which='minor',linestyle='-')

  • plt.gcf().subplots_adjust(bottom=0.15)

  • plot_confusion_matrix(cm_normalized,title='Normalizedconfusionmatrix')

  • #showconfusionmatrix

  • plt.show()

  • 結果如下圖所示:

    閱讀全文

    版權聲明:本文為博主原創文章,未經博主允許不得轉載。

    目前您尚未登錄,請登錄或注冊後進行評論

  • linchunmian

    2017-05-08 2

熱點內容
小米6實際存儲空間 發布:2024-12-22 13:41:25 瀏覽:594
sql注入補丁 發布:2024-12-22 13:32:58 瀏覽:120
小區高層消防逃生怎麼配置 發布:2024-12-22 13:29:20 瀏覽:717
伺服器配置光纖網卡ip 發布:2024-12-22 13:22:47 瀏覽:516
地圖下載源碼 發布:2024-12-22 13:18:40 瀏覽:394
navicat存儲過程導出 發布:2024-12-22 13:12:44 瀏覽:300
androidservice線程 發布:2024-12-22 13:04:57 瀏覽:302
ntplinux伺服器配置 發布:2024-12-22 12:28:23 瀏覽:268
android模擬機 發布:2024-12-22 12:26:08 瀏覽:609
貪玩藍月密碼如何修改 發布:2024-12-22 12:16:54 瀏覽:985