{
  "source_file": "0930",
  "source_platform": "研究机构",
  "author": "PyTorch Tutorials",
  "title_listed": "Word Embeddings: Encoding Lexical Semantics",
  "keywords": "词嵌入,word2vec,语义",
  "domain": "文本处理",
  "content_type": "教程",
  "is_paid_flag": "否",
  "url": "https://pytorch.org/tutorials/beginner/nlp/word_embeddings_tutorial.html",
  "publish_date": "持续更新",
  "corpus_stage": "文本处理",
  "notes": "词嵌入教程",
  "id": "5162d468a5b0",
  "collected_at": "2026-10-02T16:50:25",
  "title": "Word Embeddings: Encoding Lexical Semantics — PyTorch Tutorials 2.14.0+cu130 documentation",
  "body_markdown": "Note\nGo to the end\nto download the full example code.\nWord Embeddings: Encoding Lexical Semantics\n#\nCreated On: Apr 08, 2017 | Last Updated: Sep 14, 2021 | Last Verified: Nov 05, 2024\nWord embeddings are dense vectors of real numbers, one per word in your\nvocabulary. In NLP, it is almost always the case that your features are\nwords! But how should you represent a word in a computer? You could\nstore its ascii character representation, but that only tells you what\nthe word\nis\n, it doesn’t say much about what it\nmeans\n(you might be\nable to derive its part of speech from its affixes, or properties from\nits capitalization, but not much). Even more, in what sense could you\ncombine these representations? We often want dense outputs from our\nneural networks, where the inputs are\n\\(|V|\\)\ndimensional, where\n\\(V\\)\nis our vocabulary, but often the outputs are only a few\ndimensional (if we are only predicting a handful of labels, for\ninstance). How do we get from a massive dimensional space to a smaller\ndimensional space?\nHow about instead of ascii representations, we use a one-hot encoding?\nThat is, we represent the word\n\\(w\\)\nby\n\\[\\overbrace{\\left[ 0, 0, \\dots, 1, \\dots, 0, 0 \\right]}^\\text{|V| elements}\n\n\\]\nwhere the 1 is in a location unique to\n\\(w\\)\n. Any other word will\nhave a 1 in some other location, and a 0 everywhere else.\nThere is an enormous drawback to this representation, besides just how\nhuge it is. It basically treats all words as independent entities with\nno relation to each other. What we really want is some notion of\nsimilarity\nbetween words. Why? Let’s see an example.\nSuppose we are building a language model. Suppose we have seen the\nsentences\nThe mathematician ran to the store.\nThe physicist ran to the store.\nThe mathematician solved the open problem.\nin our training data. Now suppose we get a new sentence never before\nseen in our training data:\nThe physicist solved the open problem.\nOur language model might do OK on this sentence, but wouldn’t it be much\nbetter if we could use the following two facts:\nWe have seen  mathematician and physicist in the same role in a sentence. Somehow they\nhave a semantic relation.\nWe have seen mathematician in the same role  in this new unseen sentence\nas we are now seeing physicist.\nand then infer that physicist is actually a good fit in the new unseen\nsentence? This is what we mean by a notion of similarity: we mean\nsemantic similarity\n, not simply having similar orthographic\nrepresentations. It is a technique to combat the sparsity of linguistic\ndata, by connecting the dots between what we have seen and what we\nhaven’t. This example of course relies on a fundamental linguistic\nassumption: that words appearing in similar contexts are related to each\nother semantically. This is called the\ndistributional\nhypothesis\n.\nGetting Dense Word Embeddings\n#\nHow can we solve this problem? That is, how could we actually encode\nsemantic similarity in words? Maybe we think up some semantic\nattributes. For example, we see that both mathematicians and physicists\ncan run, so maybe we give these words a high score for the “is able to\nrun” semantic attribute. Think of some other attributes, and imagine\nwhat you might score some common words on those attributes.\nIf each attribute is a dimension, then we might give each word a vector,\nlike this:\n\\[ q_\\text{mathematician} = \\left[ \\overbrace{2.3}^\\text{can run},\n\\overbrace{9.4}^\\text{likes coffee}, \\overbrace{-5.5}^\\text{majored in Physics}, \\dots \\right]\\]\n\\[ q_\\text{physicist} = \\left[ \\overbrace{2.5}^\\text{can run},\n\\overbrace{9.1}^\\text{likes coffee}, \\overbrace{6.4}^\\text{majored in Physics}, \\dots \\right]\\]\nThen we can get a measure of similarity between these words by doing:\n\\[\\text{Similarity}(\\text{physicist}, \\text{mathematician}) = q_\\text{physicist} \\cdot q_\\text{mathematician}\n\n\\]\nAlthough it is more common to normalize by the lengths:\n\\[ \\text{Similarity}(\\text{physicist}, \\text{mathematician}) = \\frac{q_\\text{physicist} \\cdot q_\\text{mathematician}}\n{\\| q_\\text{physicist} \\| \\| q_\\text{mathematician} \\|} = \\cos (\\phi)\\]\nWhere\n\\(\\phi\\)\nis the angle between the two vectors. That way,\nextremely similar words (words whose embeddings point in the same\ndirection) will have similarity 1. Extremely dissimilar words should\nhave similarity -1.\nYou can think of the sparse one-hot vectors from the beginning of this\nsection as a special case of these new vectors we have defined, where\neach word basically has similarity 0, and we gave each word some unique\nsemantic attribute. These new vectors are\ndense\n, which is to say their\nentries are (typically) non-zero.\nBut these new vectors are a big pain: you could think of thousands of\ndifferent semantic attributes that might be relevant to determining\nsimilarity, and how on earth would you set the values of the different\nattributes? Central to the idea of deep learning is that the neural\nnetwork learns representations of the features, rather than requiring\nthe programmer to design them herself. So why not just let the word\nembeddings be parameters in our model, and then be updated during\ntraining? This is exactly what we will do. We will have some\nlatent\nsemantic attributes\nthat the network can, in principle, learn. Note\nthat the word embeddings will probably not be interpretable. That is,\nalthough with our hand-crafted vectors above we can see that\nmathematicians and physicists are similar in that they both like coffee,\nif we allow a neural network to learn the embeddings and see that both\nmathematicians and physicists have a large value in the second\ndimension, it is not clear what that means. They are similar in some\nlatent semantic dimension, but this probably has no interpretation to\nus.\nIn summary,\nword embeddings are a representation of the *semantics* of\na word, efficiently encoding semantic information that might be relevant\nto the task at hand\n. You can embed other things too: part of speech\ntags, parse trees, anything! The idea of feature embeddings is central\nto the field.\nWord Embeddings in Pytorch\n#\nBefore we get to a worked example and an exercise, a few quick notes\nabout how to use embeddings in Pytorch and in deep learning programming\nin general. Similar to how we defined a unique index for each word when\nmaking one-hot vectors, we also need to define an index for each word\nwhen using embeddings. These will be keys into a lookup table. That is,\nembeddings are stored as a\n\\(|V| \\times D\\)\nmatrix, where\n\\(D\\)\nis the dimensionality of the embeddings, such that the word assigned\nindex\n\\(i\\)\nhas its embedding stored in the\n\\(i\\)\n’th row of the\nmatrix. In all of my code, the mapping from words to indices is a\ndictionary named word_to_ix.\nThe module that allows you to use embeddings is torch.nn.Embedding,\nwhich takes two arguments: the vocabulary size, and the dimensionality\nof the embeddings.\nTo index into this table, you must use torch.LongTensor (since the\nindices are integers, not floats).\n# Author: Robert Guthrie\nimport\ntorch\nimport\ntorch.nn\nas\nnn\nimport\ntorch.nn.functional\nas\nF\nimport\ntorch.optim\nas\noptim\ntorch\n.\nmanual_seed\n(\n1\n)\n<torch._C.Generator object at 0x7f0b2677a090>\nword_to_ix\n=\n{\n\"hello\"\n:\n0\n,\n\"world\"\n:\n1\n}\nembeds\n=\nnn\n.\nEmbedding\n(\n2\n,\n5\n)\n# 2 words in vocab, 5 dimensional embeddings\nlookup_tensor\n=\ntorch\n.\ntensor\n([\nword_to_ix\n[\n\"hello\"\n]],\ndtype\n=\ntorch\n.\nlong\n)\nhello_embed\n=\nembeds\n(\nlookup_tensor\n)\nprint\n(\nhello_embed\n)\ntensor([[ 0.6614,  0.2669,  0.0617,  0.6213, -0.4519]],\n       grad_fn=<EmbeddingBackward0>)\nAn Example: N-Gram Language Modeling\n#\nRecall that in an n-gram language model, given a sequence of words\n\\(w\\)\n, we want to compute\n\\[P(w_i | w_{i-1}, w_{i-2}, \\dots, w_{i-n+1} )\n\n\\]\nWhere\n\\(w_i\\)\nis the ith word of the sequence.\nIn this example, we will compute the loss function on some training\nexamples and update the parameters with backpropagation.\nCONTEXT_SIZE\n=\n2\nEMBEDDING_DIM\n=\n10\n# We will use Shakespeare Sonnet 2\ntest_sentence\n=\n\"\"\"When forty winters shall besiege thy brow,\nAnd dig deep trenches in thy beauty's field,\nThy youth's proud livery so gazed on now,\nWill be a totter'd weed of small worth held:\nThen being asked, where all thy beauty lies,\nWhere all the treasure of thy lusty days;\nTo say, within thine own deep sunken eyes,\nWere an all-eating shame, and thriftless praise.\nHow much more praise deserv'd thy beauty's use,\nIf thou couldst answer 'This fair child of mine\nShall sum my count, and make my old excuse,'\nProving his beauty by succession thine!\nThis were to be new made when thou art old,\nAnd see thy blood warm when thou feel'st it cold.\"\"\"\n.\nsplit\n()\n# we should tokenize the input, but we will ignore that for now\n# build a list of tuples.\n# Each tuple is ([ word_i-CONTEXT_SIZE, ..., word_i-1 ], target word)\nngrams\n=\n[\n(\n[\ntest_sentence\n[\ni\n-\nj\n-\n1\n]\nfor\nj\nin\nrange\n(\nCONTEXT_SIZE\n)],\ntest_sentence\n[\ni\n]\n)\nfor\ni\nin\nrange\n(\nCONTEXT_SIZE\n,\nlen\n(\ntest_sentence\n))\n]\n# Print the first 3, just so you can see what they look like.\nprint\n(\nngrams\n[:\n3\n])\nvocab\n=\nset\n(\ntest_sentence\n)\nword_to_ix\n=\n{\nword\n:\ni\nfor\ni\n,\nword\nin\nenumerate\n(\nvocab\n)}\nclass\nNGramLanguageModeler\n(\nnn\n.\nModule\n):\ndef\n__init__\n(\nself\n,\nvocab_size\n,\nembedding_dim\n,\ncontext_size\n):\nsuper\n(\nNGramLanguageModeler\n,\nself\n)\n.\n__init__\n()\nself\n.\nembeddings\n=\nnn\n.\nEmbedding\n(\nvocab_size\n,\nembedding_dim\n)\nself\n.\nlinear1\n=\nnn\n.\nLinear\n(\ncontext_size\n*\nembedding_dim\n,\n128\n)\nself\n.\nlinear2\n=\nnn\n.\nLinear\n(\n128\n,\nvocab_size\n)\ndef\nforward\n(\nself\n,\ninputs\n):\nembeds\n=\nself\n.\nembeddings\n(\ninputs\n)\n.\nview\n((\n1\n,\n-\n1\n))\nout\n=\nF\n.\nrelu\n(\nself\n.\nlinear1\n(\nembeds\n))\nout\n=\nself\n.\nlinear2\n(\nout\n)\nlog_probs\n=\nF\n.\nlog_softmax\n(\nout\n,\ndim\n=\n1\n)\nreturn\nlog_probs\nlosses\n=\n[]\nloss_function\n=\nnn\n.\nNLLLoss\n()\nmodel\n=\nNGramLanguageModeler\n(\nlen\n(\nvocab\n),\nEMBEDDING_DIM\n,\nCONTEXT_SIZE\n)\noptimizer\n=\noptim\n.\nSGD\n(\nmodel\n.\nparameters\n(),\nlr\n=\n0.001\n)\nfor\nepoch\nin\nrange\n(\n10\n):\ntotal_loss\n=\n0\nfor\ncontext\n,\ntarget\nin\nngrams\n:\n# Step 1. Prepare the inputs to be passed to the model (i.e, turn the words\n# into integer indices and wrap them in tensors)\ncontext_idxs\n=\ntorch\n.\ntensor\n([\nword_to_ix\n[\nw\n]\nfor\nw\nin\ncontext\n],\ndtype\n=\ntorch\n.\nlong\n)\n# Step 2. Recall that torch *accumulates* gradients. Before passing in a\n# new instance, you need to zero out the gradients from the old\n# instance\nmodel\n.\nzero_grad\n()\n# Step 3. Run the forward pass, getting log probabilities over next\n# words\nlog_probs\n=\nmodel\n(\ncontext_idxs\n)\n# Step 4. Compute your loss function. (Again, Torch wants the target\n# word wrapped in a tensor)\nloss\n=\nloss_function\n(\nlog_probs\n,\ntorch\n.\ntensor\n([\nword_to_ix\n[\ntarget\n]],\ndtype\n=\ntorch\n.\nlong\n))\n# Step 5. Do the backward pass and update the gradient\nloss\n.\nbackward\n()\noptimizer\n.\nstep\n()\n# Get the Python number from a 1-element Tensor by calling tensor.item()\ntotal_loss\n+=\nloss\n.\nitem\n()\nlosses\n.\nappend\n(\ntotal_loss\n)\nprint\n(\nlosses\n)\n# The loss decreased every iteration over the training data!\n# To get the embedding of a particular word, e.g. \"beauty\"\nprint\n(\nmodel\n.\nembeddings\n.\nweight\n[\nword_to_ix\n[\n\"beauty\"\n]])\n[(['forty', 'When'], 'winters'), (['winters', 'forty'], 'shall'), (['shall', 'winters'], 'besiege')]\n[516.9433901309967, 514.5233879089355, 512.1184420585632, 509.72613310813904, 507.34616231918335, 504.9765372276306, 502.61729168891907, 500.26659202575684, 497.9251730442047, 495.592581987381]\ntensor([-0.5479, -0.8668,  0.9299,  1.5979,  0.4273,  2.5088,  0.3494, -0.0484,\n         0.1440, -1.2333], grad_fn=<SelectBackward0>)\nExercise: Computing Word Embeddings: Continuous Bag-of-Words\n#\nThe Continuous Bag-of-Words model (CBOW) is frequently used in NLP deep\nlearning. It is a model that tries to predict words given the context of\na few words before and a few words after the target word. This is\ndistinct from language modeling, since CBOW is not sequential and does\nnot have to be probabilistic. Typically, CBOW is used to quickly train\nword embeddings, and these embeddings are used to initialize the\nembeddings of some more complicated model. Usually, this is referred to\nas\npretraining embeddings\n. It almost always helps performance a couple\nof percent.\nThe CBOW model is as follows. Given a target word\n\\(w_i\\)\nand an\n\\(N\\)\ncontext window on each side,\n\\(w_{i-1}, \\dots, w_{i-N}\\)\nand\n\\(w_{i+1}, \\dots, w_{i+N}\\)\n, referring to all context words\ncollectively as\n\\(C\\)\n, CBOW tries to minimize\n\\[-\\log p(w_i | C) = -\\log \\text{Softmax}\\left(A(\\sum_{w \\in C} q_w) + b\\right)\n\n\\]\nwhere\n\\(q_w\\)\nis the embedding for word\n\\(w\\)\n.\nImplement this model in Pytorch by filling in the class below. Some\ntips:\nThink about which parameters you need to define.\nMake sure you know what shape each operation expects. Use .view() if you need to\nreshape.\nCONTEXT_SIZE\n=\n2\n# 2 words to the left, 2 to the right\nraw_text\n=\n\"\"\"We are about to study the idea of a computational process.\nComputational processes are abstract beings that inhabit computers.\nAs they evolve, processes manipulate other abstract things called data.\nThe evolution of a process is directed by a pattern of rules\ncalled a program. People create programs to direct processes. In effect,\nwe conjure the spirits of the computer with our spells.\"\"\"\n.\nsplit\n()\n# By deriving a set from `raw_text`, we deduplicate the array\nvocab\n=\nset\n(\nraw_text\n)\nvocab_size\n=\nlen\n(\nvocab\n)\nword_to_ix\n=\n{\nword\n:\ni\nfor\ni\n,\nword\nin\nenumerate\n(\nvocab\n)}\ndata\n=\n[]\nfor\ni\nin\nrange\n(\nCONTEXT_SIZE\n,\nlen\n(\nraw_text\n)\n-\nCONTEXT_SIZE\n):\ncontext\n=\n(\n[\nraw_text\n[\ni\n-\nj\n-\n1\n]\nfor\nj\nin\nrange\n(\nCONTEXT_SIZE\n)]\n+\n[\nraw_text\n[\ni\n+\nj\n+\n1\n]\nfor\nj\nin\nrange\n(\nCONTEXT_SIZE\n)]\n)\ntarget\n=\nraw_text\n[\ni\n]\ndata\n.\nappend\n((\ncontext\n,\ntarget\n))\nprint\n(\ndata\n[:\n5\n])\nclass\nCBOW\n(\nnn\n.\nModule\n):\ndef\n__init__\n(\nself\n):\npass\ndef\nforward\n(\nself\n,\ninputs\n):\npass\n# Create your model and train. Here are some functions to help you make\n# the data ready for use by your module.\ndef\nmake_context_vector\n(\ncontext\n,\nword_to_ix\n):\nidxs\n=\n[\nword_to_ix\n[\nw\n]\nfor\nw\nin\ncontext\n]\nreturn\ntorch\n.\ntensor\n(\nidxs\n,\ndtype\n=\ntorch\n.\nlong\n)\nmake_context_vector\n(\ndata\n[\n0\n][\n0\n],\nword_to_ix\n)\n# example\n[(['are', 'We', 'to', 'study'], 'about'), (['about', 'are', 'study', 'the'], 'to'), (['to', 'about', 'the', 'idea'], 'study'), (['study', 'to', 'idea', 'of'], 'the'), (['the', 'study', 'of', 'a'], 'idea')]\n\ntensor([ 3, 32, 12, 44])\nTotal running time of the script:\n(0 minutes 0.543 seconds)\nDownload\nJupyter\nnotebook:\nword_embeddings_tutorial.ipynb\nDownload\nPython\nsource\ncode:\nword_embeddings_tutorial.py\nDownload\nzipped:\nword_embeddings_tutorial.zip",
  "metadata": {
    "title": "Word Embeddings: Encoding Lexical Semantics — PyTorch Tutorials 2.14.0+cu130 documentation",
    "description": null,
    "keywords": null,
    "author": null,
    "og:image": "https://docs.pytorch.org/docs/stable/_static/img/pytorch_seo.png",
    "article:modified_time": "2022-07-20T23:02:43+00:00"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/5162d468a5b0/code/body-000.txt",
      "chars": 143,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-001.txt",
      "chars": 46,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-002.txt",
      "chars": 237,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-003.txt",
      "chars": 93,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-004.txt",
      "chars": 3260,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-005.txt",
      "chars": 429,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-006.txt",
      "chars": 1342,
      "language": "text"
    },
    {
      "file": "attachments/5162d468a5b0/code/body-007.txt",
      "chars": 232,
      "language": "text"
    }
  ],
  "images": [],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://en.wikipedia.org/wiki/Distributional_semantics",
      "label": "distributional\nhypothesis",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.manual_seed.html",
      "label": "torch . manual_seed",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.Embedding.html",
      "label": "embeds",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/tensors.html",
      "label": "lookup_tensor",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.tensor.html",
      "label": "torch . tensor",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/tensor_attributes.html",
      "label": "torch . long",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.Module.html",
      "label": "nn . Module",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.Linear.html",
      "label": "nn . Linear",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.relu.html",
      "label": "F . relu",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.log_softmax.html",
      "label": "F . log_softmax",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html",
      "label": "loss_function",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.optim.SGD.html",
      "label": "optimizer",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.Tensor.backward.html",
      "label": "loss . backward",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html",
      "label": "model . embeddings . weight",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/363afc3b7c522e4e56981679c22f1ad6/word_embeddings_tutorial.ipynb",
      "label": "Download Jupyter notebook: word_embeddings_tutorial.ipynb",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/58bdf45884d385ba7031225104b471d3/word_embeddings_tutorial.py",
      "label": "Download Python source code: word_embeddings_tutorial.py",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/81ac1e09d57b4487bbbafee5f7e669b8/word_embeddings_tutorial.zip",
      "label": "Download zipped: word_embeddings_tutorial.zip",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:53:58Z",
  "source_url": "https://pytorch.org/tutorials/beginner/nlp/word_embeddings_tutorial.html",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 14493,
  "expected_body_images": 0,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/5162d468a5b0/pages/source.html",
  "local_html": "attachments/5162d468a5b0/pages/article.html",
  "body_base_path": "attachments/5162d468a5b0/pages/",
  "body_markdown_path": "attachments/5162d468a5b0/pages/article.md"
}