{'fraction_non_alphanumeric': 0.023708241166127842, 'fraction_numerical': 0.006068855992286314, 'mean_word_length': 4.715397082658023, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Topology of Learning in Artificial Neural Networks

Understanding how neural networks learn remains one of the central challenges in machine learning research. From random at the start of training, the weights of a neural network evolve in such a way as to be able to perform a variety of tasks, like classifying images. Here we study the emergence of structure in the weights by applying methods from topological data analysis. We train simple feedforward neural networks on the MNIST dataset and monitor the evolution of the weights. When initialized to zero, the weights follow trajectories that branch off recurrently, thus generating trees that describe the growth of the effective capacity of each layer. When initialized to tiny random values, the weights evolve smoothly along two-dimensional surfaces. We show that natural coordinates on these learning surfaces correspond to important factors of variation.


Introduction
Deep artificial neural networks perform spectacularly on many machine learning tasks, including image classification, speech recognition, translation, and game playing. A neural network can for example be trained to detect the presence of a dog in an image by analyzing a large number of images that have been labeled as "dog" or "no dog," each time adjusting its parameters, in particular the weights assigned to edges connecting pairs of neurons. Such a neural network is generally organized in layers that learn increasingly abstract features, from simple combinations of input pixels all the way to full-fledged models of a dog [1].
Despite these empirical successes, neural networks are still poorly understood theoretically. One open question is why they generalize so well to unseen samples, whereas the multitude of their parameters would lead one to expect them to overfit the training set [2,3]. Finding the answer would make neural networks more interpretable and provide a principled approach to designing their architecture.
The main intuition behind this paper is that whatever the structure that arises during training may be, it should be possible to capture it with topology, roughly defined as the mathematical study of qualitative shapes and structures. More specifically, before starting the training the weights are typically initialized randomly and are therefore structureless. However, as the training progresses the weights learn to adjust towards certain distributions of values, whose structure ultimately encodes the knowledge of the neural network about the task at hand. It is the emergence of such learning structures that we wish to exhibit in this paper.
Our approach is to monitor the evolution of the weights during training. For a fixed layer of the neural network, we consider each of its neurons at each training step as a vector of incoming weights. This provides us in the end with a cloud of points in a high-dimensional vector space. We study the shape of this point cloud by applying techniques from topological data analysis [4]. This allows us to represent the evolution of the weights as a graph that encodes the topological structure of the point cloud. The code for this paper uses the Keras library [5] and is available as a Jupyter Notebook [6].
This work was originally motivated by the papers [7,8], where topological methods are also used to study the behavior of weights in neural networks. Their approach is however substantially different, as it focuses on exposing circular point clouds representing transformations of 3 × 3 convolutional filters.

From point clouds to graphs
In Data Science, a dataset usually consists of a collection of samples (observations) described by a number of features (variables). The first step in topological data analysis is to represent each sample as a point in a space that has one dimension per feature. The dataset thus takes the form of a cloud of data points in feature space. The main goal is then to study whether this point cloud has some interesting shape, involving for example branches or loops.
One popular tool to visualize certain topological properties of a dataset is the so-called "Mapper algorithm" [9] (Figure 1). The idea is to construct a graph that captures the topological structure of the original point cloud in the high-dimensional feature space.
Given a point cloud in a space X, the Mapper algorithm first requires to choose a continuous map f : X → Z to a space Z. This map is usually called the filter function and can be for example the projection to a subspace of X. The next choice is a finite open covering U = {U i } i∈I of Z. A clustering algorithm is then chosen and applied to each pre-image f −1 (U i ) independently, resulting in an open covering V = {V j } j∈J of the point cloud. The final Mapper graph (or, more generally, simplicial complex) is then given by the nerve of V, that is the set of finite subsets of the index set J with non-empty intersections: N (V) = {K ⊆ J| ∩ k∈K V k = ∅}. A subset of n + 1 indices describes an n-simplex. In particular, subsets with one element correspond to the vertices of the graph, and subsets with two elements to its edges. Insightful applications of the Mapper algorithm can be found for example in [10]. In this paper, we will use the convenient Python implementation KeplerMapper [11]. Here the point cloud has the shape of a tree in X = R 2 . The filter function f : X → Z is given by the distance from the origin, and Z = R is covered by 3 overlapping intervals (blue, red, green). Clustering each pre-image leads to a covering V of the point cloud, whose nerve N (V) provides the graph shown on the right. The size of each vertex indicates the number of elements in the corresponding cluster, while edges connect clusters with common elements.

Learning graphs
We will now construct Mapper graphs that represent the learning of the weights for each layer of a fully connected feedforward neural network. For a given layer i with N i neurons, we track the evolution of the incoming weights for each neuron. In other words, we are considering the columns of the weight matrix between layers i − 1 and i. At the beginning of the training the weights are initialized randomly (or to zero), but they evolve to more useful values as they learn. The learning is performed by stochastic gradient descent with minibatches. After each training step (a fixed number of minibatches), we record N i weight vectors of size N i−1 , interpreted as N i points in a space of dimension N i−1 . By the end of the training we thus have a point cloud of n steps × N i points in N i−1 dimensions, whose shape should capture some meaningful aspects of the learning process of the weights ( Figure 2).
Since the number of neuron per layer is typically much larger than two or three, the resulting point cloud lives in a large number of dimensions and cannot be immediately visualized. We will apply standard techniques for dimensionality reduction, like principal component analysis (PCA), to obtain two-dimensional representations. However, as we will see, the results can be fairly involved and hard to decipher. Fortunately, the Mapper algorithm reviewed in Section 2 will produce clean graphs that will allow us to easily study topological properties of the evolution of weights during training.

Symmetric initialization and branching trees
We start by studying a neural network with one hidden layer of 100 neurons, trained by stochastic gradient descent on the MNIST dataset of handwritten digits [12]. For simplicity we turn off all biases and only consider weights as parameters. We take sigmoid activation functions for the internal layers, and softmax for the output layer, with the cross-entropy as the loss function.
Initializing all the weights of a neural network to the same value is generally not recommended in practice [13]. One of the main guidelines for initialization is indeed to break the symmetry between the weights, so that the neurons can learn different functions. However, since our goal in this paper is not to reach optimal performance but rather to gain some insight into how weights learn, we start by studying the simplest case where all weights are initialized to zero.
We find that the evolution of the weights during training describes a tree, with subsets of weights occasionally branching off from each other. While this can already be deduced from inspection of the PCA projections, the topological structure of the tree is much easier to grasp from the Mapper graphs ( Figure 3). Here we used the L 2 norm as the filter function to take advantage of the fact that the branches grow from the origin, and DBSCAN as the clustering algorithm. digits. Interestingly, the discrimination abilities of the model are correlated with the branchings. For example, after a phase where every digit is classified as a 1, the digit 9 gets mostly mistaken for a 7, up to the point when the corresponding branches separate in the learning graph ( Figure 4).
The weights of the hidden layer with 100 neurons evolve in a similar way. After a period of slow evolution (not visible on the graph), they start to branch off recurrently, often at the same time on different branches. However, in contrast to the case of the output layer, the number of branches at the end of the training does not match the number of hidden neurons. We indeed end up with only 12 distinct branches, which can be taken as an indication of the effective capacity of the hidden layer. Additional branchings could of course be produced by extending the training beyond 50 epochs, but it is difficult to find hyper-parameters that lead to the apparition of a maximal number of branches. It would be interesting to determine which conditions lead to maximal branching.
We note that the shape of the weight trajectories is remarkably constant from one training to the next. This seems to indicate that branching is triggered in a deterministic way. We leave a more complete investigation of the mechanism of branching to future work.

Tiny random initialization and learning surfaces
We now turn our attention to the evolution of weights when they are initialized at tiny random values. We consider a neural network with two hidden layers of 100 neurons each and sigmoid activation functions. The weights are initialized with a normal distribution with mean µ = 0 and standard deviation σ = 10 −6 . We train the network on MNIST and record the evolution of the weights throughout training for each layer ( Figure 5).
The weights of the output layer follow a similar evolution to the case with zero initialization. A phase of slow progression away from the origin is followed by a branching phase and the development of a tree with 10 distinctive branches, associated with the 10 digit classes. The behavior of the weights for the first hidden layer is more surprising (Figure 6 left): after following the same trajectory for a while, all the weights branch off simultaneously and appear to evolve in parallel along a smooth surface! This coordination appears to break off eventually, and the weights veer away from the surface in arbitrary directions. It is however possible that this apparently chaotic phase is an artifact of the PCA projections, and that the weights in fact continue to evolve along a smooth surface in higher dimensions (projecting a curtain to the floor would give a noisy curve. . . ). This interpretation is supported by the smooth evolution of the weight norms towards the end of training (Figure 8).
The corresponding learning graph is again a tree, in which the surface has been decomposed into branches. This is due to the fact that with the L 2 norm as filter function the edges of the graph are mostly created in the radial direction from the origin, rather than in the lateral direction of the surface. In order to better exhibit the surface we can instead take the filter function to be the first 3 PCA directions. The learning graph then contains a densely connected grid that corresponds to the surface (Figure 6 right). With an implementation of the Mapper algorithm taking into account 2-simplices, this would look like a triangulated surface.
This learning surface is remarkably invariant from one training to another. While the shape of the surface could have been expected to be determined by the exact random values of the initial weights, it appears in fact to be independent of the random seed. Moreover, the surface varies continuously under small changes in the number of neurons, learning rate, batch size, or mean µ and standard deviation σ of the normal initialization. Comparing the cases of neural networks with one and two hidden layers (Figures 3 and 5) we also observe a striking similarity between the weight trajectories for the last two layers.  Figure 5. Several phases are visible: uniform evolution (blue), parallel evolution along a surface (green), chaotic evolution (yellow). Right: learning graph representing the surface as a densely connected grid (filter function given by the first 3 PCA directions).
One idea to try to understand the meaning of the learning surface is to study deformations of the weights as we move on it. Natural coordinates on the surface are provided by the training time and the lateral spread of the diversifying neurons. Sampling neurons along these two dimensions, we can reshape the corresponding weight vectors into 28 × 28 images and study the factors of variation. The images themselves appear rather homogenous, but taking differences between nearby images (for each training step) reveals interesting patterns ( Figure 7). As the training progresses, shapes of digits emerge from white noise. For a fixed training step, moving across the surface corresponds to morphing digits into one another, for example a 1 into a 3 into a 0 as in the last row of Figure 7. This should be compared with the 2d latent manifolds learned with variational auto-encoders in [14]. It is therefore tempting to conjecture that the learning surface is shaped to capture dominant factors of variation.
Finally, we turn to the evolution of the weights of the second hidden layer (Figure 5 middle). The weights first evolve slowly all together along a line, but then they split into two groups, one of which shoots off in the opposite direction, back to the origin and beyond. The two groups of weights undergo a second phase of slow evolution on opposite ends of the line. Branching takes place relatively late and produces surfaces shaped like palm leaves. This case is thus some hybrid between a tree and a learning surface.  The uniform increase is triggered by branching in the output layer. The branching is followed by a short period of reshuffling, before a converging period. Bottom: The accuracy increases in jumps: 10% (chance), 40%, 80% (with more training steps, this would be followed by a slow increase towards 95%).
The evolutions of the different layers can be easily compared by looking at plots of the norms of the weights (Figure 8). During the phase of slow evolution (epochs 0-27), the most noticeable progress is a steady increase in the norms of the weights of the second hidden layer. Branching between the 10 neurons of the output layer then takes place around epoch 28, accompanied by a sharp increase in the weights of the first hidden layer, and the characteristic binary splitting of the weights in the second hidden layer (curiously, the blue curve looks like minus the derivative of the red one). Correspondingly, the accuracy of the model, which was so far attributing all test images to a single class, jumps up to around 40%. Further inflections in the accuracy occur when the neurons of the first hidden layer spread out into the learning surface (epoch 45), and when the weights of the second hidden layer branch off into palm leaves (epoch 56). The training was interrupted earlier in order to focus on the smooth part of the learning surface, but the accuracy would have otherwise steadily increased towards 96% as the weight norms converged.

Discussion
We have presented a method to visualize the evolution of weights during the training of a fully connected feedforward neural network. It would be desirable to obtain a better theoretical understanding of the various phenomena that we have observed. The remarkable regularity of weight trajectories begs the question of how they are determined and what triggers branching, perhaps from the perspective of bifurcation theory. Similarly, the properties of learning surfaces deserve further study, for example by defining some Riemannian metric on them or by representing them as algebraic curves. Furthermore, the surprising appearance of two-dimensional structures in parameter spaces with hundreds of dimensions could provide some clues to explain the uncanny generalization aptitudes of neural networks. Constraining the weights to evolve on a surface may indeed act as an implicit regularization [15].
Extensions of our work include studying how learning graphs are impacted by initialization schemes, optimization methods, regularization, biases, activation functions, and depth. It would also be interesting to explore learning graphs for convolutional and recurrent neural networks.
While our main hope was to gain insights into learning in neural networks, our approach can also have practical applications, for example in guiding the choice of architecture and hyper-parameters. We can imagine that quantitative properties of learning graphs, such as the degrees or centralities used in network science, could provide reliable measures to improve the quality of the learning.