mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-11-09 21:51:42 +08:00
Remove breaks to improve readability
This commit is contained in:
parent
cd2c3bd5a8
commit
026945e669
1 changed files with 0 additions and 52 deletions
|
|
@ -39,8 +39,6 @@ Systems of equations are a central theme in numerical computing.
|
||||||
These equations are often expressed and solved with multidimensional
|
These equations are often expressed and solved with multidimensional
|
||||||
arrays. For example, this is a two dimensional array:
|
arrays. For example, this is a two dimensional array:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{bmatrix}
|
\begin{bmatrix}
|
||||||
1 & 2 \\
|
1 & 2 \\
|
||||||
|
|
@ -48,8 +46,6 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Elixir programmers typically express a similar data structure using
|
Elixir programmers typically express a similar data structure using
|
||||||
a list of lists, like this:
|
a list of lists, like this:
|
||||||
|
|
||||||
|
|
@ -77,8 +73,6 @@ than `Enum.map/2` and `Enum.reduce/3`.
|
||||||
In this section, we'll look at some of the various tools for
|
In this section, we'll look at some of the various tools for
|
||||||
creating and interacting with tensors.
|
creating and interacting with tensors.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
To get started, we'll first need to include the Nx dependency.
|
To get started, we'll first need to include the Nx dependency.
|
||||||
In Livebook, we can simply use Mix install. At the time of this writing,
|
In Livebook, we can simply use Mix install. At the time of this writing,
|
||||||
there's no Hex package for Nx, so we'll use a git
|
there's no Hex package for Nx, so we'll use a git
|
||||||
|
|
@ -102,8 +96,6 @@ Now, everything is set up, so we're ready to create some tensors.
|
||||||
|
|
||||||
### Creating tensors
|
### Creating tensors
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Start out by getting a feel for Nx through its documentation.
|
Start out by getting a feel for Nx through its documentation.
|
||||||
Do so through the IEx helpers, like this:
|
Do so through the IEx helpers, like this:
|
||||||
|
|
||||||
|
|
@ -138,8 +130,6 @@ The result shows all of the major fields that make up a tensor:
|
||||||
* The shape of the tensor, going left to right, with the outside dimensions listed first.
|
* The shape of the tensor, going left to right, with the outside dimensions listed first.
|
||||||
* The names of each dimension.
|
* The names of each dimension.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We can easily convert it to a binary:
|
We can easily convert it to a binary:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
|
@ -168,8 +158,6 @@ because they must often be processed. Elixir binaries make quick work
|
||||||
of dealing with numerical data structured for platforms other than
|
of dealing with numerical data structured for platforms other than
|
||||||
Elixir.
|
Elixir.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We can get any cell of the tensor:
|
We can get any cell of the tensor:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
|
@ -200,8 +188,6 @@ Now,
|
||||||
* return a `{2, 2}` tensor containing the first two columns
|
* return a `{2, 2}` tensor containing the first two columns
|
||||||
of the first two rows
|
of the first two rows
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We can get information about this most recent term with
|
We can get information about this most recent term with
|
||||||
the IEx helper `i`, like this:
|
the IEx helper `i`, like this:
|
||||||
|
|
||||||
|
|
@ -223,8 +209,6 @@ to get more documentation about tensors. We could also open an Elixir
|
||||||
cell, type Nx.tensor, and hover the cursor over the word `tensor`
|
cell, type Nx.tensor, and hover the cursor over the word `tensor`
|
||||||
to see the help about that function.
|
to see the help about that function.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We can get the shape of the tensor with `Nx.shape/1`:
|
We can get the shape of the tensor with `Nx.shape/1`:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
|
@ -242,8 +226,6 @@ changes the metadata, so it has no notable cost.
|
||||||
|
|
||||||
The new tensor has the same type, but a new shape.
|
The new tensor has the same type, but a new shape.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Now, reshape the tensor to contain three dimensions with
|
Now, reshape the tensor to contain three dimensions with
|
||||||
one batch, one row, and four columns.
|
one batch, one row, and four columns.
|
||||||
|
|
||||||
|
|
@ -263,8 +245,6 @@ Nx.tensor([[1, 2, 3]], names: [:rows, :cols], type: {:u, 8})
|
||||||
We created a tensor of the shape `{1, 3}`, with the type `u8`,
|
We created a tensor of the shape `{1, 3}`, with the type `u8`,
|
||||||
the values `[1, 2, 3]`, and two axes named `rows` and `cols`.
|
the values `[1, 2, 3]`, and two axes named `rows` and `cols`.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Now we know how to create tensors, so it's time to do something with them.
|
Now we know how to create tensors, so it's time to do something with them.
|
||||||
|
|
||||||
## Tensor aware functions
|
## Tensor aware functions
|
||||||
|
|
@ -324,8 +304,6 @@ Nx.sum(tensor, axes: [:x])
|
||||||
Nx sums the values across the `x` dimension: `1 + 2` in the first row
|
Nx sums the values across the `x` dimension: `1 + 2` in the first row
|
||||||
and `3 + 4` in the second row.
|
and `3 + 4` in the second row.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Now,
|
Now,
|
||||||
|
|
||||||
* create a `{2, 2, 2}` tensor
|
* create a `{2, 2, 2}` tensor
|
||||||
|
|
@ -341,8 +319,6 @@ Sometimes, we need to combine two tensors together with an
|
||||||
operator. Let's say we wanted to subtract one tensor from
|
operator. Let's say we wanted to subtract one tensor from
|
||||||
another. Mathematically, the expression looks like this:
|
another. Mathematically, the expression looks like this:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{bmatrix}
|
\begin{bmatrix}
|
||||||
5 & 6 \\
|
5 & 6 \\
|
||||||
|
|
@ -358,8 +334,6 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
To solve this problem, add each integer on the left with the
|
To solve this problem, add each integer on the left with the
|
||||||
corresponding integer on the right. Unfortunately, we cannot
|
corresponding integer on the right. Unfortunately, we cannot
|
||||||
use Elixir's built-in subtraction operator as it is not tensor-aware.
|
use Elixir's built-in subtraction operator as it is not tensor-aware.
|
||||||
|
|
@ -383,8 +357,6 @@ Often, the dimensions of tensors in an operator don't match.
|
||||||
For example, you might want to subtract a `1` from every
|
For example, you might want to subtract a `1` from every
|
||||||
element of a `{2, 2}` tensor, like this:
|
element of a `{2, 2}` tensor, like this:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{bmatrix}
|
\begin{bmatrix}
|
||||||
1 & 2 \\
|
1 & 2 \\
|
||||||
|
|
@ -396,8 +368,6 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Mathematically, it's the same as this:
|
Mathematically, it's the same as this:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
|
|
@ -415,8 +385,6 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
That means we need a way to convert `1` to a `{2, 2}` tensor.
|
That means we need a way to convert `1` to a `{2, 2}` tensor.
|
||||||
`Nx.broadcast/2` solves that problem. This function takes
|
`Nx.broadcast/2` solves that problem. This function takes
|
||||||
a tensor or a scalar and a shape.
|
a tensor or a scalar and a shape.
|
||||||
|
|
@ -451,8 +419,6 @@ Nx.subtract(10, tensor)
|
||||||
|
|
||||||
Or subtract a row or column. Mathematically, it would look like this:
|
Or subtract a row or column. Mathematically, it would look like this:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{bmatrix}
|
\begin{bmatrix}
|
||||||
1 & 2 \\
|
1 & 2 \\
|
||||||
|
|
@ -467,12 +433,8 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
which is the same as this:
|
which is the same as this:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{bmatrix}
|
\begin{bmatrix}
|
||||||
1 & 2 \\
|
1 & 2 \\
|
||||||
|
|
@ -488,8 +450,6 @@ $$
|
||||||
\end{bmatrix}
|
\end{bmatrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
This rewrite happens in Nx too, also through a broadcast. We want to
|
This rewrite happens in Nx too, also through a broadcast. We want to
|
||||||
broadcast the tensor `[1, 2]` to match the `{2, 2}` shape, like this:
|
broadcast the tensor `[1, 2]` to match the `{2, 2}` shape, like this:
|
||||||
|
|
||||||
|
|
@ -531,8 +491,6 @@ h Nx.broadcast
|
||||||
Much of the time, you won't have to broadcast yourself. Many of
|
Much of the time, you won't have to broadcast yourself. Many of
|
||||||
the functions and operators Nx supports will do so automatically.
|
the functions and operators Nx supports will do so automatically.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We can use tensor-aware operators via various `Nx` functions and
|
We can use tensor-aware operators via various `Nx` functions and
|
||||||
many of them implicitly broadcast tensors.
|
many of them implicitly broadcast tensors.
|
||||||
|
|
||||||
|
|
@ -556,8 +514,6 @@ over classic Elixir functions.
|
||||||
individual operations and using a just-in-time (JIT) compiler to emit
|
individual operations and using a just-in-time (JIT) compiler to emit
|
||||||
highly specialized native code for the desired computation unit.
|
highly specialized native code for the desired computation unit.
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
We don't have to do anything special to get access to
|
We don't have to do anything special to get access to
|
||||||
get tensor awareness beyond importing `Nx.Defn` and writing
|
get tensor awareness beyond importing `Nx.Defn` and writing
|
||||||
our code within a `defn` block.
|
our code within a `defn` block.
|
||||||
|
|
@ -612,8 +568,6 @@ defn subtract(a, b) do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Now, it's your turn. Add a `defn` to `TensorMath`
|
Now, it's your turn. Add a `defn` to `TensorMath`
|
||||||
that accepts two tensors representing the lengths of sides of a
|
that accepts two tensors representing the lengths of sides of a
|
||||||
right triangle and uses the pythagorean theorem to return the
|
right triangle and uses the pythagorean theorem to return the
|
||||||
|
|
@ -647,20 +601,14 @@ a function returning the gradient. We have two functions: `poly/1`
|
||||||
is a simple numerical definitin, and `poly_slope_at/1` returns
|
is a simple numerical definitin, and `poly_slope_at/1` returns
|
||||||
its gradient:
|
its gradient:
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
poly: f(x) = 3x^2 + 2x + 1 \\
|
poly: f(x) = 3x^2 + 2x + 1 \\
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
polySlopeAt: g(x) = 6x + 2
|
polySlopeAt: g(x) = 6x + 2
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<!-- livebook:{"break_markdown":true} -->
|
|
||||||
|
|
||||||
Here's the Elixir equivalent of those functions:
|
Here's the Elixir equivalent of those functions:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue