Phản từ trăn

Câu lệnh vòng lặp while trong ngôn ngữ lập trình Python lặp đi lặp lại việc thực thi câu lệnh đích miễn là một điều kiện nhất định là đúng

cú pháp

Cú pháp của vòng lặp while trong ngôn ngữ lập trình Python là -

while expression:
   statement(s)

Ở đây, (các) câu lệnh có thể là một câu lệnh đơn lẻ hoặc một khối các câu lệnh. Điều kiện có thể là bất kỳ biểu thức nào và true là bất kỳ giá trị khác 0 nào. Vòng lặp lặp khi điều kiện đúng

Khi điều kiện trở thành sai, điều khiển chương trình chuyển đến dòng ngay sau vòng lặp

Trong Python, tất cả các câu lệnh được thụt vào bởi cùng một số khoảng trắng ký tự sau cấu trúc lập trình được coi là một phần của một khối mã. Python sử dụng thụt đầu dòng làm phương pháp nhóm các câu lệnh

sơ đồ dòng chảy

Phản từ trăn

Ở đây, điểm mấu chốt của vòng lặp while là vòng lặp có thể không bao giờ chạy. Khi điều kiện được kiểm tra và kết quả là sai, thân vòng lặp sẽ bị bỏ qua và câu lệnh đầu tiên sau vòng lặp while sẽ được thực hiện

Ví dụ

Bản trình diễn trực tiếp
#!/usr/bin/python

count = 0
while (count < 9):
   print 'The count is:', count
   count = count + 1

print "Good bye!"

Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -

The count is: 0
The count is: 1
The count is: 2
The count is: 3
The count is: 4
The count is: 5
The count is: 6
The count is: 7
The count is: 8
Good bye!

Khối ở đây, bao gồm các câu lệnh in và tăng, được thực hiện lặp đi lặp lại cho đến khi số đếm không nhỏ hơn 9. Với mỗi lần lặp lại, giá trị hiện tại của số lượng chỉ mục được hiển thị và sau đó tăng thêm 1

Vòng lặp vô hạn

Một vòng lặp trở thành vòng lặp vô hạn nếu một điều kiện không bao giờ trở thành FALSE. Bạn phải thận trọng khi sử dụng vòng lặp while vì có khả năng điều kiện này không bao giờ chuyển thành giá trị FALSE. Điều này dẫn đến một vòng lặp không bao giờ kết thúc. Một vòng lặp như vậy được gọi là một vòng lặp vô hạn

Một vòng lặp vô hạn có thể hữu ích trong lập trình máy khách/máy chủ nơi máy chủ cần chạy liên tục để các chương trình máy khách có thể giao tiếp với nó khi cần thiết

#!/usr/bin/python

var = 1
while var == 1 :  # This constructs an infinite loop
   num = raw_input("Enter a number  :")
   print "You entered: ", num

print "Good bye!"

Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -

Enter a number  :20
You entered:  20
Enter a number  :29
You entered:  29
Enter a number  :3
You entered:  3
Enter a number between :Traceback (most recent call last):
   File "test.py", line 5, in 
      num = raw_input("Enter a number :")
KeyboardInterrupt

Ví dụ trên diễn ra trong một vòng lặp vô hạn và bạn cần sử dụng CTRL+C để thoát khỏi chương trình

Sử dụng Tuyên bố khác với Vòng lặp While

Python hỗ trợ để có một câu lệnh khác được liên kết với một câu lệnh vòng lặp

  • Nếu câu lệnh khác được sử dụng với vòng lặp while, câu lệnh khác được thực thi khi điều kiện trở thành sai

Ví dụ sau minh họa sự kết hợp của câu lệnh other với câu lệnh while in ra một số miễn là nó nhỏ hơn 5, nếu không thì câu lệnh khác sẽ được thực thi

Bản trình diễn trực tiếp
#!/usr/bin/python

count = 0
while count < 5:
   print count, " is  less than 5"
   count = count + 1
else:
   print count, " is not less than 5"

Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -

0 is less than 5
1 is less than 5
2 is less than 5
3 is less than 5
4 is less than 5
5 is not less than 5

Suite Độc Lập

Tương tự như cú pháp câu lệnh if, nếu mệnh đề while của bạn chỉ bao gồm một câu lệnh duy nhất, thì nó có thể được đặt trên cùng một dòng với tiêu đề while

Đây là cú pháp và ví dụ về mệnh đề while một dòng -

#!/usr/bin/python

flag = 1
while (flag): print 'Given flag is really true!'
print "Good bye!"

Tốt hơn là không thử ví dụ trên vì nó đi vào vòng lặp vô hạn và bạn cần nhấn tổ hợp phím CTRL+C để thoát

Có một nhược điểm rất lớn đối với đại diện này, bên cạnh việc nó lớn đến mức nào. Về cơ bản, nó coi tất cả các từ là các thực thể độc lập không có mối quan hệ nào với nhau. Những gì chúng tôi thực sự muốn là một số khái niệm về sự giống nhau giữa các từ. Tại sao?

Giả sử chúng ta đang xây dựng một mô hình ngôn ngữ. Giả sử chúng ta đã thấy những câu

  • Nhà toán học chạy đến cửa hàng

  • Nhà vật lý chạy đến cửa hàng

  • Nhà toán học giải bài toán mở

trong dữ liệu đào tạo của chúng tôi. Bây giờ, giả sử chúng ta nhận được một câu mới chưa từng thấy trong dữ liệu đào tạo của mình

  • Nhà vật lý giải bài toán mở

Mô hình ngôn ngữ của chúng tôi có thể làm tốt câu này, nhưng sẽ không tốt hơn nhiều nếu chúng tôi có thể sử dụng hai sự kiện sau

  • Chúng ta đã thấy nhà toán học và nhà vật lý có cùng vai trò trong một câu. Bằng cách nào đó họ có một mối quan hệ ngữ nghĩa

  • Chúng ta đã thấy nhà toán học trong cùng một vai trò trong câu mới chưa được nhìn thấy này như chúng ta đang thấy nhà vật lý

và sau đó suy luận rằng nhà vật lý thực sự phù hợp với câu mới chưa từng thấy? . chúng tôi muốn nói đến sự giống nhau về ngữ nghĩa, không chỉ đơn giản là có các biểu diễn chính tả tương tự. Đó là một kỹ thuật để chống lại sự thưa thớt của dữ liệu ngôn ngữ, bằng cách kết nối các dấu chấm giữa những gì chúng ta đã thấy và những gì chúng ta chưa thấy. Tất nhiên, ví dụ này dựa trên một giả định ngôn ngữ cơ bản. rằng các từ xuất hiện trong các ngữ cảnh tương tự có liên quan với nhau về mặt ngữ nghĩa. Đây được gọi là giả thuyết phân phối

Nhận nhúng từ dày đặc

Làm thế nào chúng ta có thể giải quyết vấn đề này? . Ví dụ: chúng tôi thấy rằng cả nhà toán học và nhà vật lý đều có thể chạy, vì vậy có thể chúng tôi cho những từ này điểm cao cho thuộc tính ngữ nghĩa “có thể chạy”. Nghĩ về một số thuộc tính khác và tưởng tượng xem bạn có thể cho điểm một số từ phổ biến về những thuộc tính đó như thế nào

Nếu mỗi thuộc tính là một thứ nguyên, thì chúng ta có thể cung cấp cho mỗi từ một vectơ, như thế này

\[ q_\text{nhà toán học} = \left[ \overbrace{2. 3}^\text{có thể chạy}, \overbrace{9. 4}^\text{thích cà phê}, \overbrace{-5. 5}^\text{chuyên ngành Vật lý}, \dots \right]\]

\[ q_\text{nhà vật lý} = \left[ \overbrace{2. 5}^\text{có thể chạy}, \overbrace{9. 1}^\text{thích cà phê}, \overbrace{6. 4}^\text{chuyên ngành Vật lý}, \dots \right]\]

Sau đó, chúng ta có thể có được một biện pháp tương tự giữa những từ này bằng cách làm

\[\text{Tính tương tự}(\text{nhà vật lý}, \text{nhà toán học}) = q_\text{nhà vật lý} \cdot q_\text{nhà toán học} \]

Mặc dù phổ biến hơn là chuẩn hóa theo độ dài

\[ \text{Tính tương tự}(\text{nhà vật lý}, \text{nhà toán học}) = \frac{q_\text{nhà vật lý} \cdot q_\text{nhà toán học}} {\. q_\text{nhà vật lý} \. \. q_\text{nhà toán học} \. } = \cos (\phi)\]

Trong đó \(\phi\) là góc giữa hai vectơ. Theo cách đó, các từ cực kỳ giống nhau (các từ có phần nhúng chỉ theo cùng một hướng) sẽ có độ tương tự 1. Các từ cực kỳ khác nhau nên có độ tương đồng -1.

Bạn có thể coi các vectơ one-hot thưa thớt từ đầu phần này là trường hợp đặc biệt của các vectơ mới này mà chúng tôi đã xác định, trong đó mỗi từ về cơ bản có độ tương tự bằng 0 và chúng tôi đã gán cho mỗi từ một thuộc tính ngữ nghĩa duy nhất nào đó. Các vectơ mới này dày đặc, có nghĩa là các mục nhập của chúng (thường) khác không

Nhưng những vectơ mới này là một nỗi đau lớn. bạn có thể nghĩ ra hàng nghìn thuộc tính ngữ nghĩa khác nhau có thể liên quan đến việc xác định tính tương đồng và bạn sẽ đặt giá trị của các thuộc tính khác nhau như thế nào? . Vậy tại sao không chỉ để từ nhúng là tham số trong mô hình của chúng tôi và sau đó được cập nhật trong quá trình đào tạo? . Về nguyên tắc, chúng ta sẽ có một số thuộc tính ngữ nghĩa tiềm ẩn mà mạng có thể học. Lưu ý rằng từ nhúng có thể sẽ không thể hiểu được. Đó là, mặc dù với các vectơ được tạo thủ công ở trên, chúng ta có thể thấy rằng các nhà toán học và vật lý giống nhau ở chỗ họ đều thích cà phê, nếu chúng ta cho phép một mạng lưới thần kinh học các phép nhúng và thấy rằng cả nhà toán học và vật lý đều có giá trị lớn trong . Chúng giống nhau ở một số khía cạnh ngữ nghĩa tiềm ẩn, nhưng điều này có lẽ không có cách giải thích nào đối với chúng tôi

Tóm lại, nhúng từ là sự thể hiện *ngữ nghĩa* của một từ, mã hóa thông tin ngữ nghĩa một cách hiệu quả có thể liên quan đến nhiệm vụ hiện tại. Bạn cũng có thể nhúng những thứ khác. một phần của thẻ lời nói, cây phân tích cú pháp, bất cứ thứ gì. Ý tưởng nhúng tính năng là trung tâm của lĩnh vực này

Nhúng từ trong Pytorch

Trước khi chúng ta đến với một ví dụ đã làm và một bài tập, một vài lưu ý nhanh về cách sử dụng các phần nhúng trong Pytorch và trong lập trình học sâu nói chung. Tương tự như cách chúng ta xác định chỉ mục duy nhất cho mỗi từ khi tạo vectơ one-hot, chúng ta cũng cần xác định chỉ mục cho mỗi từ khi sử dụng nhúng. Đây sẽ là những chìa khóa trong một bảng tra cứu. Nghĩa là, các phần nhúng được lưu trữ dưới dạng \(. V. \times D\) ma trận, trong đó \(D\) là thứ nguyên của phần nhúng, sao cho . Trong tất cả mã của tôi, ánh xạ từ từ sang chỉ mục là từ điển có tên word_to_ix. \(i\) has its embedding stored in the \(i\)’th row of the matrix. In all of my code, the mapping from words to indices is a dictionary named word_to_ix.

Mô-đun cho phép bạn sử dụng nhúng là ngọn đuốc. nn. Nhúng, có hai đối số. kích thước từ vựng và kích thước của các phần nhúng

Để lập chỉ mục vào bảng này, bạn phải sử dụng đèn pin. LongTensor (vì các chỉ số là số nguyên, không phải số float)

________số 8_______


word_to_ix = {"hello": 0, "world": 1}
embeds = nn.Embedding(2, 5)  # 2 words in vocab, 5 dimensional embeddings
lookup_tensor = torch.tensor([word_to_ix["hello"]], dtype=torch.long)
hello_embed = embeds(lookup_tensor)
print(hello_embed)

tensor([[ 0.6614,  0.2669,  0.0617,  0.6213, -0.4519]],
       grad_fn=)

Một ví dụ. Mô hình hóa ngôn ngữ N-Gram

Hãy nhớ rằng trong một mô hình ngôn ngữ n-gram, cho một chuỗi các từ \(w\) , chúng tôi muốn tính toán

\[P(w_i. w_{i-1}, w_{i-2}, \dots, w_{i-n+1} ) \]

Trong đó \(w_i\) là từ thứ i của dãy.

Trong ví dụ này, chúng tôi sẽ tính toán hàm mất mát trên một số ví dụ đào tạo và cập nhật các tham số bằng lan truyền ngược

CONTEXT_SIZE = 2
EMBEDDING_DIM = 10
# We will use Shakespeare Sonnet 2
test_sentence = """When forty winters shall besiege thy brow,
And dig deep trenches in thy beauty's field,
Thy youth's proud livery so gazed on now,
Will be a totter'd weed of small worth held:
Then being asked, where all thy beauty lies,
Where all the treasure of thy lusty days;
To say, within thine own deep sunken eyes,
Were an all-eating shame, and thriftless praise.
How much more praise deserv'd thy beauty's use,
If thou couldst answer 'This fair child of mine
Shall sum my count, and make my old excuse,'
Proving his beauty by succession thine!
This were to be new made when thou art old,
And see thy blood warm when thou feel'st it cold.""".split()
# we should tokenize the input, but we will ignore that for now
# build a list of tuples.
# Each tuple is ([ word_i-CONTEXT_SIZE, ..., word_i-1 ], target word)
ngrams = [
    (
        [test_sentence[i - j - 1] for j in range(CONTEXT_SIZE)],
        test_sentence[i]
    )
    for i in range(CONTEXT_SIZE, len(test_sentence))
]
# Print the first 3, just so you can see what they look like.
print(ngrams[:3])

vocab = set(test_sentence)
word_to_ix = {word: i for i, word in enumerate(vocab)}


class NGramLanguageModeler(nn.Module):

    def __init__(self, vocab_size, embedding_dim, context_size):
        super(NGramLanguageModeler, self).__init__()
        self.embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.linear1 = nn.Linear(context_size * embedding_dim, 128)
        self.linear2 = nn.Linear(128, vocab_size)

    def forward(self, inputs):
        embeds = self.embeddings(inputs).view((1, -1))
        out = F.relu(self.linear1(embeds))
        out = self.linear2(out)
        log_probs = F.log_softmax(out, dim=1)
        return log_probs


losses = []
loss_function = nn.NLLLoss()
model = NGramLanguageModeler(len(vocab), EMBEDDING_DIM, CONTEXT_SIZE)
optimizer = optim.SGD(model.parameters(), lr=0.001)

for epoch in range(10):
    total_loss = 0
    for context, target in ngrams:

        # Step 1. Prepare the inputs to be passed to the model (i.e, turn the words
        # into integer indices and wrap them in tensors)
        context_idxs = torch.tensor([word_to_ix[w] for w in context], dtype=torch.long)

        # Step 2. Recall that torch *accumulates* gradients. Before passing in a
        # new instance, you need to zero out the gradients from the old
        # instance
        model.zero_grad()

        # Step 3. Run the forward pass, getting log probabilities over next
        # words
        log_probs = model(context_idxs)

        # Step 4. Compute your loss function. (Again, Torch wants the target
        # word wrapped in a tensor)
        loss = loss_function(log_probs, torch.tensor([word_to_ix[target]], dtype=torch.long))

        # Step 5. Do the backward pass and update the gradient
        loss.backward()
        optimizer.step()

        # Get the Python number from a 1-element Tensor by calling tensor.item()
        total_loss += loss.item()
    losses.append(total_loss)
print(losses)  # The loss decreased every iteration over the training data!

# To get the embedding of a particular word, e.g. "beauty"
print(model.embeddings.weight[word_to_ix["beauty"]])

[(['forty', 'When'], 'winters'), (['winters', 'forty'], 'shall'), (['shall', 'winters'], 'besiege')]
[517.997193813324, 515.3646864891052, 512.7484903335571, 510.1485164165497, 507.56221628189087, 504.9897267818451, 502.4295496940613, 499.87967133522034, 497.3393235206604, 494.8069131374359]
tensor([ 0.2199, -0.5751,  1.4575,  1.7721, -2.0176,  0.4216,  0.5747, -1.7962,
         1.2480,  1.2744], grad_fn=)

Bài tập. Máy tính nhúng Word. Túi từ liên tục

Mô hình Túi từ liên tục (CBOW) thường được sử dụng trong học sâu NLP. Đó là một mô hình cố gắng dự đoán các từ trong ngữ cảnh của một vài từ trước và một vài từ sau từ mục tiêu. Điều này khác với mô hình hóa ngôn ngữ, vì CBOW không tuần tự và không nhất thiết phải mang tính xác suất. Thông thường, CBOW được sử dụng để đào tạo nhanh các nhúng từ và các nhúng này được sử dụng để khởi tạo các nhúng của một số mô hình phức tạp hơn. Thông thường, điều này được gọi là nhúng trước. Nó hầu như luôn giúp hiệu suất một vài phần trăm