主頁 > 後端開發 > python3.6+torch1.2實作Sentiment Analysis(資料集MR)

python3.6+torch1.2實作Sentiment Analysis(資料集MR)

2020-12-24 13:10:07 後端開發

總共是下面幾個檔案:
在這里插入圖片描述
注意,最后一個是json檔案,里面是電影影評資料集MR的劃分出來的訓練集生成的詞典,是個字典檔案,也可以自己再弄一個,

在這里插入圖片描述
在訓練集上訓練了10個epoch,結果大概是上圖這個樣子

1、創建model_para.py檔案,里面是模型的超引數,

import argparse

class Hpara():
    parser  =  argparse.ArgumentParser()    
    ############# insert paras #############
    parser.add_argument('--batch_size',default = 16, type = int) # batch_size
    parser.add_argument('--epochs',default = 1, type = int) # epochs
    
    parser.add_argument('--lr',default = 3*10**(-5), type = float) # learning rate
    parser.add_argument('--l2_lambda',default = 0.0, type = float) # L2_loss lambda
    parser.add_argument('--seg_net_nums_layer',default = 6, type = int) # segnet Rnn Layers
    parser.add_argument('--seg_net_dropout_rate',default = 0.2, type = float) # segnet dropout rate
    parser.add_argument('--seg_net_hidden_size',default = 64, type = int) # segnet hidden size 
    parser.add_argument('--seg_net_n_best',default = 12, type = int) # sample nums
    parser.add_argument('--seg_net_beam_size',default = 8, type = int) # beam size
    parser.add_argument('--seg_net_rnntype',default = 'GRU', type = str) # segnet Rnn Type
    parser.add_argument('--is_bi_rnn',default = True, type = bool) # segnet bi_Rnn 
    parser.add_argument('--unfreezing_bert_nums',default = 12, type = int)
    
    parser.add_argument('--is_training_bert',default = True, type = bool) 
    parser.add_argument('--is_load_best_model', default = False ,type = bool)
    
    ## MLP model paras
    parser.add_argument('--MLP_hidden_nums_layer',default = 1, type = int)
    parser.add_argument('--Bert_drop_out',default = 0.1, type = float)
    

    ## SA model paras
    parser.add_argument('--SA_hidden_dim',default = 256, type = int)
    parser.add_argument('--SA_is_bi',default = True, type = bool)
    parser.add_argument('--SA_dropout_rate',default = 0.4, type = float)
    parser.add_argument('--SA_word_dim',default = 300, type = int)
    parser.add_argument('--SA_vocab_size',default = 16783, type = int)
    parser.add_argument('--SA_layer_nums',default = 2, type = int)
    parser.add_argument('--SA_Rnn_type',default = 'LSTM', type = str)
    
    
    parser.add_argument('--pretrained_bert_path',default = '/bert-base-uncased', type = str)
    parser.add_argument('--bert_out_size',default = 768, type = int)
    parser.add_argument('--bert_vocab_path',default = /bert-base-uncased/vocab.txt', type = str)
    
    parser.add_argument('--saved_model_path',default = './best_model', type = str)
    parser.add_argument('--final_model_path',default = './final_epoch_saved_model', type = str)
    
    ## SegNet model paras
    parser.add_argument('--pretrained_segnet_model',default = './segnet_model/trained_model.torchsave', type = str)
    parser.add_argument('--seg_net_vocab',default = './segnet_model/all_vocabulary.pickle', type = str)
    parser.add_argument('--seg_net_vocab_size',default = 16703, type = int)
    parser.add_argument('--seg_net_embed_size',default = 300, type = int)
    
    parser.add_argument('--seg_net_use_cuda',default = False, type = bool)
    parser.add_argument('--seg_net_finetuning',default = False, type = bool)
    parser.add_argument('--seg_net_isbanor',default = True, type = bool)
    

    
    ## Other paras
    
    parser.add_argument('--emotion_label_nums',default = 2, type = int)
 
    parser.add_argument('--train_csv',default = r'./data/train_1.csv', type = str)
    parser.add_argument('--test_csv',default = r'./data/test_1.csv', type = str)
    parser.add_argument('--val_csv',default = r'./data/val_1.csv', type = str)

這個里面的引數是我在別的一個專案里面直接復制過來的,很多引數沒有修改,實際使用到的引數很少,可以在代碼里面自己看一下

2、創建資料處理檔案data_utils.py

該檔案主要用來加載資料集,并且分成batch輸入到模型里面,還有最重要的對文本按照長度進行排序,這樣做的目的是LSTM或者別的RNN在計算的時候不考慮padding,

import numpy as np

import json
import pandas as pd

def del_none(text): # delete ‘’ 洗掉使用空格切分之后句子里面的長度為0的字串
    new_text = []
    
    for t in text:
        ws = t.split(' ')
        ws = [w for w in ws if w != '']
        new_text.append(' '.join(ws))
        
    return new_text

def read_csv(para):# read Moive Review DataSet
    
    train_data = pd.read_csv(para.train_csv, delimiter=',')
    test_data = pd.read_csv(para.test_csv, delimiter=',')
    val_data = pd.read_csv(para.val_csv, delimiter=',')
       
    train_text = list(train_data['INPUT'])
    train_label = list(train_data['OUTPUT'])
    
    test_text = list(test_data['INPUT'])
    test_label = list(test_data['OUTPUT'])
    
    val_text = list(val_data['INPUT'])
    val_label = list(val_data['OUTPUT'])
    
    train_text = del_none(train_text)
    test_text = del_none(test_text)
    val_text = del_none(val_text)
    train_label = np.array(train_label, dtype=np.int32)
    test_label = np.array(test_label, dtype=np.int32)
    val_label = np.array(val_label, dtype=np.int32)
    

    
    return train_text, test_text, val_text, train_label, test_label, val_label


def create_dict(train_text): 
    for t in train_text:
        ws = t.split(' ')
        aw.extend(ws)
        
    vocab = list(set(aw))
    
    vd = dict(zip(vocab, range(2,len(vocab)+2)))
    
    vd['UNKNOWN'] = 1
    vd['PADDING'] = 0
    
    with open('vd.json', 'w', encoding='utf-8') as f:
        json.dump(vd, f)
        
 
def get_vd(path):   
    f = open(path,'r', encoding='utf-8')
    vd = json.load(f)
    return vd

def text2id(text, vd):
    bs = len(text)
    lens = [len(t.split(' ')) for t in text]
    ml = max(lens)
    text_id = np.zeros(shape = (bs, ml), dtype=np.int32)
    words = list(vd.keys())
    for i in range(bs):
        ws = text[i].split(' ')
        for j in range(lens[i]):
            if ws[j] in words:
                text_id[i,j] = vd[ws[j]]
            else:
                text_id[i, j] = vd['UNKNOWN']
    return text_id, lens

            
def sort_data_by_length(textid, label, lengths):
   
    lengths = np.array(lengths, dtype=np.int32)
    idx = np.argsort(lengths)
    idx = idx[::-1]
    
    
    lengths = lengths[idx]  
    sc_id = textid[idx]
    label = label[idx]
  
    return sc_id, label, lengths


    
def batch_iter_str(text, label , batch_size = 16):
    
    path = 'vd.json'
    vd = get_vd(path)
    
    data_nums = len(text)
    
    num_batch = (data_nums + batch_size - 1) // batch_size
    indices = np.random.permutation(np.arange(data_nums))

    text = [text[i] for i in indices]
    label = label[indices]
   
    for i in range(num_batch):
        
        start_offset = i * batch_size
        end_offset = min(start_offset + batch_size, data_nums)

        bt_text = text[start_offset:end_offset]
        bt_label = label[start_offset:end_offset]
        
        text_id, lens = text2id(bt_text, vd)

        sc_id, bt_label, lengths = sort_data_by_length(text_id, bt_label, lens)
          
        
        yield i, num_batch, sc_id, bt_label, lengths

3、創建Model.py檔案

import torch.nn as nn
import torch


device = torch.device("cuda:4" if torch.cuda.is_available() else "cpu")

class sa_model(nn.Module):
    
    def __init__(self, para):
        
        super(sa_model, self).__init__()
        self.para = para
        
        if para.SA_Rnn_type == 'LSTM': 
            
            self.RNN = nn.LSTM(input_size = para.SA_word_dim,
                               hidden_size = para.SA_hidden_dim,
                               num_layers = para.SA_layer_nums, 
                               batch_first = True,
                               dropout = para.SA_dropout_rate,
                               bidirectional = para.SA_is_bi)
        elif para.SA_Rnn_type == 'GRU':  
            
           self.RNN = nn.GRU(input_size = para.SA_word_dim, 
                               hidden_size = para.SA_hidden_dim, 
                               num_layers = para.SA_layer_nums, 
                               batch_first = True, 
                               dropout = para.SA_dropout_rate, 
                               bidirectional = para.SA_is_bi)
            
        elif para.SA_Rnn_type == 'RNN':
            
            self.RNN = nn.RNN(input_size = para.SA_word_dim, 
                               hidden_size = para.SA_hidden_dim, 
                               num_layers = para.SA_layer_nums, 
                               batch_first = True, 
                               dropout = para.SA_dropout_rate, 
                               bidirectional = para.SA_is_bi)
            
        self.nnEm = nn.Embedding(para.SA_vocab_size, para.SA_word_dim, padding_idx = 0).to(device)
        
        self.criterion = nn.CrossEntropyLoss()
        
        self.linear = nn.Linear(para.SA_hidden_dim*2, para.emotion_label_nums)

        
    
        
    
    
    def forward(self, x, x_len, label):
        
        x = self.nnEm(x)
        
        packed_embeds = nn.utils.rnn.pack_padded_sequence(x, x_len, batch_first=True)
        
        out, hs = self.RNN(packed_embeds)
        
        out, _ = nn.utils.rnn.pad_packed_sequence(out,
                                                  batch_first=True)
        
        h1 = hs[0][0]
        
        h2 = hs[0][1]
        
        h = torch.cat([h1, h2], dim = 1)
        logits = self.linear(h)
        
        loss = self.criterion(logits, label)
        
        pred = torch.argmax(torch.nn.functional.softmax(logits, dim = 1), dim = 1)
        
        return loss, pred

4、創建train.py檔案

from Model import sa_model
from data_utils import batch_iter_str, read_csv
import torch
from model_para import Hpara
import torch.optim as optim
import matplotlib.pyplot as plt
from tqdm import tqdm
import os
from sklearn.metrics import accuracy_score
device = torch.device("cuda:4" if torch.cuda.is_available() else "cpu")
print(device)






def train(text, label, model, epoch):
    
    optimizer = optim.RMSprop(filter(lambda p: p.requires_grad, model.parameters()), lr = para.lr * (0.95)**epoch)

    pred_label = []
    true_label = []
    all_loss = []
    model.train()
    db = batch_iter_str(text, label)
    
    for i, num_batch, sc_id, label, lengths in db:
        sc_id = torch.tensor(sc_id).long().to(device)
        label = torch.tensor(label).long().to(device)
        lens = torch.tensor(lengths).long().to(device)
        
        model.zero_grad()
        loss ,pred = model(sc_id, lens, label)
        
        all_loss.append(loss)
        pred_label.append(pred)
        true_label.append(label)
        
        loss.backward()
        optimizer.step()
        
        if (i+1)%10 == 0:
            print('%d step loss is : %f'%(i+1, loss.item()))
            print('%d acc is : %f'%(i+1, accuracy_score(label.data.cpu().numpy(), pred.data.cpu().numpy())))
     

    mean_loss = sum(all_loss) / num_batch
    pred_label = torch.cat(pred_label, dim = 0)
    true_label = torch.cat(true_label, dim = 0)
    mean_acc = accuracy_score(true_label, pred_label)

    return mean_loss, mean_acc

def test(saved_acc, text, label, model, mode = 'validation'):
     
    pred_label = []
    true_label = []
    all_loss = []
    
    model.eval()
    
    db = batch_iter_str(text, label)
    
    for i, num_batch, sc_id, label, lengths in db:
        
        sc_id = torch.tensor(sc_id).long().to(device)
        label = torch.tensor(label).long().to(device)
        lens = torch.tensor(lengths).long().to(device)
        
        model.zero_grad()
        loss ,pred = model(sc_id, lens, label)
        
        all_loss.append(loss)
        pred_label.append(pred)
        true_label.append(label)
        
                  
    mean_loss = sum(all_loss) / num_batch
    pred_label = torch.cat(pred_label, dim = 0)
    true_label = torch.cat(true_label, dim = 0)
    mean_acc = accuracy_score(true_label, pred_label)
    
    if mode == 'validation':# save the best model when the mode is 'validation' 
        if mean_acc >= saved_acc:
            torch.save(model, os.path.join(para.saved_model_path,'My_model_pth'))
            saved_acc = mean_acc
        ## TODO: the next step is to save the model every epoch
        torch.save(model, os.path.join(para.final_model_path,'My_model_pth'))
    
        
    
    return mean_loss, mean_acc, saved_acc
        
def load_model(para, model, best_model = True):
    if best_model:
        model_path = para.saved_model_path
    else:
        model_path = para.final_model_path
        
    if os.path.exists(os.path.join(model_path, 'My_model_pth')):
        print('model path is : ', model_path)
        model = torch.load(os.path.join(model_path, 'My_model_pth'))
        print('load pre-train')
    else:
        model = model

    return model
    

        
        
        
if __name__ == '__main__':
    
    saved_acc = 0.0
    hp=Hpara()
    parser = hp.parser
    para = parser.parse_args()
    
    train_text, test_text, val_text, train_label, test_label, val_label = read_csv(para)
    
    model = sa_model(para)
    model = model.to(device)
    
    if para.is_load_best_model:
        
        print('load the best model...')
        _, _, saved_acc = test(saved_acc, val_text, val_label, model, mode = 'get_saved_acc')
        model = load_model(para, model)
        
    else:
        
        print('load the final epoch model...')
        _, _, saved_acc = test(saved_acc, val_text, val_label, model, mode = 'get_saved_acc') 
        model = load_model(para, model, best_model = False)
    
    print('saved accuracy is :', saved_acc)
    
    train_loss = []
    train_acc = []
    
    val_loss = []
    val_acc = []
    
    test_loss = []
    test_acc = []
    
    for i in range(para.epochs): 
        ########### train ###########
        train_mean_loss_i, train_mean_acc_i = train(train_text, train_label, model, i)
        
        train_loss.append(train_mean_loss_i)
        train_acc.append(train_mean_acc_i)
        
        ########## val #############
        val_loss_i, val_acc_i, saved_acc = test(saved_acc, val_text, val_label, model, )
        print('%d epoch val acc is', val_acc_i)
        val_loss.append(val_loss_i)
        val_acc.append(val_acc_i)
        
        ########## test ###########
        test_loss_i, test_acc_i, saved_acc = test(saved_acc, test_text, test_label, model, mode = 'test')
        
        print('%d epoch test acc is :', test_acc_i)
        
        test_loss.append(test_loss_i)
        test_acc.append(test_acc_i)
        
        
    
    plt.figure(2)
    plt.subplot(231)
    plt.plot(train_loss)
    plt.xlabel('epochs')
    plt.ylabel('emotion_train_loss')
    
    plt.subplot(232)
    plt.plot(test_loss)
    plt.xlabel('epochs')
    plt.ylabel('emotion_test_loss')
    
    plt.subplot(233)
    plt.plot(val_loss)
    plt.xlabel('epochs')
    plt.ylabel('emotion_val_loss')

    plt.subplot(234)
    plt.plot(train_acc)
    plt.xlabel('epochs')
    plt.ylabel('emotion_train_acc')
    
    plt.subplot(235)
    plt.plot(test_acc)
    plt.xlabel('epochs')
    plt.ylabel('emotion_test_acc')

    plt.subplot(236)
    plt.plot(val_acc)
    plt.xlabel('epochs')
    plt.ylabel('emotion_val_acc')        

    plt.show()

5、完整的代碼

鏈接:https://pan.baidu.com/s/1nWMThnz9eK8zVggQJ7Umag
提取碼:0rwq
復制這段內容后打開百度網盤手機App,操作更方便哦

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/239676.html

標籤:python

上一篇:演算法題:實作 strStr()函式

下一篇:一起學爬蟲(Python) — 19 年輕人,進來學自動化

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more